more patches (#5811)
This commit is contained in:
parent
0c2d1544ac
commit
2ba2c29b2e
53 changed files with 711 additions and 1074 deletions
|
@ -1,27 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 23 Jul 2018 22:18:31 -0400
|
||||
Subject: [PATCH] Mark chunk dirty anytime entities change to guarantee it
|
||||
saves
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
index d69ccb1f31f31ebeee477df20ce1410f9e485eb7..bd9b19d988ecf72e099efeff6ec3483a352174ec 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
@@ -559,6 +559,7 @@ public class LevelChunk implements ChunkAccess {
|
||||
entity.zChunk = this.chunkPos.z;
|
||||
this.entities.add(entity); // Paper - per chunk entity list
|
||||
this.entitySlices[k].add(entity);
|
||||
+ this.markUnsaved(); // Paper
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -587,6 +588,7 @@ public class LevelChunk implements ChunkAccess {
|
||||
return;
|
||||
}
|
||||
entityCounts.decrement(entity.getMinecraftKeyString());
|
||||
+ this.markUnsaved(); // Paper
|
||||
// Paper end
|
||||
this.entities.remove(entity); // Paper
|
||||
}
|
|
@ -1,99 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 23 Jul 2018 22:44:23 -0400
|
||||
Subject: [PATCH] Add some Debug to Chunk Entity slices
|
||||
|
||||
If we detect unexpected state, log and try to recover
|
||||
|
||||
This should hopefully avoid duplicate entities ever being created
|
||||
if the entity was to end up in 2 different chunk slices
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
index a2cc3e58d59ed3d9f443b77c44d8200cc09b4da9..7847078c54154e28ab066ea8a329f929df1e1a37 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -156,6 +156,7 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s
|
||||
}
|
||||
}
|
||||
};
|
||||
+ public List<Entity> entitySlice = null;
|
||||
// Paper end
|
||||
|
||||
public com.destroystokyo.paper.loottable.PaperLootableInventoryData lootableData; // Paper
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
index bd9b19d988ecf72e099efeff6ec3483a352174ec..09aa608bd303b618ae2c0ebd237bcbdba60a37a8 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
@@ -26,7 +26,9 @@ import net.minecraft.ReportedException;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
+import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ChunkHolder;
|
||||
+import net.minecraft.server.level.ServerChunkCache;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
@@ -550,6 +552,25 @@ public class LevelChunk implements ChunkAccess {
|
||||
if (k >= this.entitySlices.length) {
|
||||
k = this.entitySlices.length - 1;
|
||||
}
|
||||
+ // Paper - remove from any old list if its in one
|
||||
+ List<Entity> nextSlice = this.entitySlices[k]; // the next list to be added to
|
||||
+ List<Entity> currentSlice = entity.entitySlice;
|
||||
+ if (nextSlice == currentSlice) {
|
||||
+ if (Level.DEBUG_ENTITIES) MinecraftServer.LOGGER.warn("Entity was already in this chunk!" + entity, new Throwable());
|
||||
+ return; // ??? silly plugins
|
||||
+ }
|
||||
+ if (currentSlice != null && currentSlice.contains(entity)) {
|
||||
+ // Still in an old chunk...
|
||||
+ if (Level.DEBUG_ENTITIES) MinecraftServer.LOGGER.warn("Entity is still in another chunk!" + entity, new Throwable());
|
||||
+ LevelChunk chunk = entity.getCurrentChunk();
|
||||
+ if (chunk != null) {
|
||||
+ chunk.removeEntity(entity);
|
||||
+ } else {
|
||||
+ removeEntity(entity);
|
||||
+ }
|
||||
+ currentSlice.remove(entity); // Just incase the above did not remove from the previous slice
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
if (!entity.inChunk || entity.getCurrentChunk() != this) entityCounts.increment(entity.getMinecraftKeyString()); // Paper
|
||||
entity.inChunk = true;
|
||||
@@ -559,6 +580,7 @@ public class LevelChunk implements ChunkAccess {
|
||||
entity.zChunk = this.chunkPos.z;
|
||||
this.entities.add(entity); // Paper - per chunk entity list
|
||||
this.entitySlices[k].add(entity);
|
||||
+ entity.entitySlice = this.entitySlices[k]; // Paper
|
||||
this.markUnsaved(); // Paper
|
||||
}
|
||||
|
||||
@@ -584,6 +606,10 @@ public class LevelChunk implements ChunkAccess {
|
||||
|
||||
// Paper start
|
||||
if (entity.currentChunk != null && entity.currentChunk.get() == this) entity.setCurrentChunk(null);
|
||||
+ if (entitySlices[section] == entity.entitySlice) {
|
||||
+ entity.entitySlice = null;
|
||||
+ entity.inChunk = false;
|
||||
+ }
|
||||
if (!this.entitySlices[section].remove(entity)) {
|
||||
return;
|
||||
}
|
||||
@@ -742,7 +768,7 @@ public class LevelChunk implements ChunkAccess {
|
||||
// Paper start - neighbour cache
|
||||
int chunkX = this.chunkPos.x;
|
||||
int chunkZ = this.chunkPos.z;
|
||||
- ChunkProviderServer chunkProvider = ((ServerLevel)this.world).getChunkSource();
|
||||
+ ServerChunkCache chunkProvider = ((ServerLevel)this.world).getChunkSource();
|
||||
for (int dx = -NEIGHBOUR_CACHE_RADIUS; dx <= NEIGHBOUR_CACHE_RADIUS; ++dx) {
|
||||
for (int dz = -NEIGHBOUR_CACHE_RADIUS; dz <= NEIGHBOUR_CACHE_RADIUS; ++dz) {
|
||||
LevelChunk neighbour = chunkProvider.getChunkAtIfLoadedMainThreadNoCache(chunkX + dx, chunkZ + dz);
|
||||
@@ -802,7 +828,7 @@ public class LevelChunk implements ChunkAccess {
|
||||
// Paper start - neighbour cache
|
||||
int chunkX = this.chunkPos.x;
|
||||
int chunkZ = this.chunkPos.z;
|
||||
- ChunkProviderServer chunkProvider = ((ServerLevel)this.world).getChunkSource();
|
||||
+ ServerChunkCache chunkProvider = ((ServerLevel)this.world).getChunkSource();
|
||||
for (int dx = -NEIGHBOUR_CACHE_RADIUS; dx <= NEIGHBOUR_CACHE_RADIUS; ++dx) {
|
||||
for (int dz = -NEIGHBOUR_CACHE_RADIUS; dz <= NEIGHBOUR_CACHE_RADIUS; ++dz) {
|
||||
LevelChunk neighbour = chunkProvider.getChunkAtIfLoadedMainThreadNoCache(chunkX + dx, chunkZ + dz);
|
|
@ -1,152 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Fri, 27 Jul 2018 22:36:31 -0500
|
||||
Subject: [PATCH] SkeletonHorse Additions
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/EntitySelector.java b/src/main/java/net/minecraft/world/entity/EntitySelector.java
|
||||
index a3bad391a719363077740aa810c9412df34b4ae5..e92a8c4c49c452e1f3f0c06398f2a74e3432262f 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/EntitySelector.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/EntitySelector.java
|
||||
@@ -25,6 +25,7 @@ public final class EntitySelector {
|
||||
public static final Predicate<Entity> ATTACK_ALLOWED = (entity) -> {
|
||||
return !(entity instanceof Player) || !entity.isSpectator() && !((Player) entity).isCreative() && entity.level.getDifficulty() != Difficulty.PEACEFUL;
|
||||
};
|
||||
+ public static Predicate<Entity> notSpectator() { return NO_SPECTATORS; } // Paper - OBFHELPER
|
||||
public static final Predicate<Entity> NO_SPECTATORS = (entity) -> {
|
||||
return !entity.isSpectator();
|
||||
};
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/SkeletonHorse.java b/src/main/java/net/minecraft/world/entity/animal/horse/SkeletonHorse.java
|
||||
index 7ef99acaa24525c68b1528bd3232738baab8e1c6..eaab482ae341ddda0754e726357cd845121fb043 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/horse/SkeletonHorse.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/horse/SkeletonHorse.java
|
||||
@@ -26,7 +26,7 @@ public class SkeletonHorse extends AbstractHorse {
|
||||
|
||||
private final SkeletonTrapGoal skeletonTrapGoal = new SkeletonTrapGoal(this);
|
||||
private boolean isTrap;
|
||||
- private int trapTime;
|
||||
+ private int trapTime; public int getTrapTime() { return this.trapTime; } // Paper - OBFHELPER
|
||||
|
||||
public SkeletonHorse(EntityType<? extends SkeletonHorse> type, Level world) {
|
||||
super(type, world);
|
||||
@@ -145,10 +145,12 @@ public class SkeletonHorse extends AbstractHorse {
|
||||
return 0.96F;
|
||||
}
|
||||
|
||||
+ public boolean isTrap() { return this.isTrap(); } // Paper - OBFHELPER
|
||||
public boolean isTrap() {
|
||||
return this.isTrap;
|
||||
}
|
||||
|
||||
+ public void setTrap(boolean trap) { this.setTrap(trap); } // Paper - OBFHELPER
|
||||
public void setTrap(boolean trapped) {
|
||||
if (trapped != this.isTrap) {
|
||||
this.isTrap = trapped;
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/SkeletonTrapGoal.java b/src/main/java/net/minecraft/world/entity/animal/horse/SkeletonTrapGoal.java
|
||||
index 6c2cbaae2afe076c8b7bc53ffa91fe37e423d120..7f5fb28a7deabe1b62ed21e5ed1ea1ecca0d15b8 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/horse/SkeletonTrapGoal.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/horse/SkeletonTrapGoal.java
|
||||
@@ -14,10 +14,14 @@ import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.item.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.world.level.Level;
|
||||
+import org.bukkit.entity.HumanEntity;
|
||||
+
|
||||
+import java.util.List;
|
||||
|
||||
public class SkeletonTrapGoal extends Goal {
|
||||
|
||||
private final SkeletonHorse horse;
|
||||
+ private List<HumanEntity> eligiblePlayers; // Paper
|
||||
|
||||
public SkeletonTrapGoal(SkeletonHorse skeletonHorse) {
|
||||
this.horse = skeletonHorse;
|
||||
@@ -25,12 +29,13 @@ public class SkeletonTrapGoal extends Goal {
|
||||
|
||||
@Override
|
||||
public boolean canUse() {
|
||||
- return this.horse.level.hasNearbyAlivePlayer(this.horse.getX(), this.horse.getY(), this.horse.getZ(), 10.0D);
|
||||
+ return !(eligiblePlayers = this.horse.level.findNearbyBukkitPlayers(this.horse.getX(), this.horse.getY(), this.horse.getZ(), 10.0D, false)).isEmpty(); // Paper
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
ServerLevel worldserver = (ServerLevel) this.horse.level;
|
||||
+ if (!new com.destroystokyo.paper.event.entity.SkeletonHorseTrapEvent((org.bukkit.entity.SkeletonHorse) this.horse.getBukkitEntity(), eligiblePlayers).callEvent()) return; // Paper
|
||||
DifficultyInstance difficultydamagescaler = worldserver.getCurrentDifficultyAt(this.horse.blockPosition());
|
||||
|
||||
this.horse.setTrap(false);
|
||||
diff --git a/src/main/java/net/minecraft/world/level/EntityGetter.java b/src/main/java/net/minecraft/world/level/EntityGetter.java
|
||||
index 66681b9f0e2531d3da25629e44180417b32b4d66..6a5430fe54a5c8ad119a0f3842961825a54d8d7a 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/EntityGetter.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/EntityGetter.java
|
||||
@@ -1,6 +1,9 @@
|
||||
package net.minecraft.world.level;
|
||||
|
||||
+import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Lists;
|
||||
+import org.bukkit.entity.HumanEntity;
|
||||
+
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
@@ -115,6 +118,28 @@ public interface EntityGetter {
|
||||
return entityhuman;
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ default List<HumanEntity> findNearbyBukkitPlayers(double x, double y, double z, double radius, boolean notSpectator) {
|
||||
+ return findNearbyBukkitPlayers(x, y, z, radius, notSpectator ? EntitySelector.notSpectator() : EntitySelector.canAITarget());
|
||||
+ }
|
||||
+
|
||||
+ default List<HumanEntity> findNearbyBukkitPlayers(double x, double y, double z, double radius, @Nullable Predicate<Entity> predicate) {
|
||||
+ ImmutableList.Builder<HumanEntity> builder = ImmutableList.builder();
|
||||
+
|
||||
+ for (Player human : this.players()) {
|
||||
+ if (predicate == null || predicate.test(human)) {
|
||||
+ double distanceSquared = human.getDistanceSquared(x, y, z);
|
||||
+
|
||||
+ if (radius < 0.0D || distanceSquared < radius * radius) {
|
||||
+ builder.add(human.getBukkitEntity());
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return builder.build();
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Nullable
|
||||
default Player getNearestPlayer(Entity entity, double maxDistance) {
|
||||
return this.getNearestPlayer(entity.getX(), entity.getY(), entity.getZ(), maxDistance, false);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeletonHorse.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeletonHorse.java
|
||||
index b52ca4a612e30542ef4029cb1340f616bc4c36e6..7f984639fc2697cad9d0393467b0cb896d1e55a4 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeletonHorse.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeletonHorse.java
|
||||
@@ -25,4 +25,26 @@ public class CraftSkeletonHorse extends CraftAbstractHorse implements SkeletonHo
|
||||
public Variant getVariant() {
|
||||
return Variant.SKELETON_HORSE;
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public net.minecraft.world.entity.animal.horse.SkeletonHorse getHandle() {
|
||||
+ return (net.minecraft.world.entity.animal.horse.SkeletonHorse) super.getHandle();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getTrapTime() {
|
||||
+ return getHandle().getTrapTime();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isTrap() {
|
||||
+ return getHandle().isTrap();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setTrap(boolean trap) {
|
||||
+ getHandle().setTrap(trap);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
|
@ -1,127 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Thu, 26 Jul 2018 00:11:12 -0400
|
||||
Subject: [PATCH] Prevent Saving Bad entities to chunks
|
||||
|
||||
See https://github.com/PaperMC/Paper/issues/1223
|
||||
|
||||
Minecraft is saving invalid entities to the chunk files.
|
||||
|
||||
Avoid saving bad data, and also make improvements to handle
|
||||
loading these chunks. Any invalid entity will be instant killed,
|
||||
so lets avoid adding it to the world...
|
||||
|
||||
This lets us be safer about the dupe UUID resolver too, as now
|
||||
we can ignore instant killed entities and avoid risk of duplicating
|
||||
an invalid entity.
|
||||
|
||||
This should reduce log occurrences of dupe uuid messages.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
index a5d7781b13a6d61238d026f064512f7162e1e868..8e8e5f30c512ed7d8ee987550c22d3e9df845043 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -1151,6 +1151,7 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
|
||||
List[] aentityslice = chunk.getEntitySlices(); // Spigot
|
||||
int i = aentityslice.length;
|
||||
|
||||
+ java.util.List<Entity> toMoveChunks = new java.util.ArrayList<>(); // Paper
|
||||
for (int j = 0; j < i; ++j) {
|
||||
List<Entity> entityslice = aentityslice[j]; // Spigot
|
||||
Iterator iterator = entityslice.iterator();
|
||||
@@ -1163,11 +1164,25 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
|
||||
throw (IllegalStateException) Util.pauseInIde((Throwable) (new IllegalStateException("Removing entity while ticking!")));
|
||||
}
|
||||
|
||||
+ // Paper start - move out entities that shouldn't be in this chunk before it unloads
|
||||
+ if (!entity.removed && (int) Math.floor(entity.getX()) >> 4 != chunk.getPos().x || (int) Math.floor(entity.getZ()) >> 4 != chunk.getPos().z) {
|
||||
+ toMoveChunks.add(entity);
|
||||
+ continue;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
this.entitiesById.remove(entity.getId());
|
||||
this.onEntityRemoved(entity);
|
||||
+
|
||||
+ if (entity.removed) iterator.remove(); // Paper - don't save dead entities during unload
|
||||
}
|
||||
}
|
||||
}
|
||||
+ // Paper start - move out entities that shouldn't be in this chunk before it unloads
|
||||
+ for (Entity entity : toMoveChunks) {
|
||||
+ this.updateChunkPos(entity);
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
|
||||
index 0efaf4d0f58bcf38b427e76bf09b96e354294159..542d6f322df5f44ad9f504c8e14c88e3fa540657 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
|
||||
@@ -27,6 +27,7 @@ import net.minecraft.nbt.LongArrayTag;
|
||||
import net.minecraft.nbt.ShortTag;
|
||||
import net.minecraft.server.level.ServerChunkCache;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
+import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.server.level.ThreadedLevelLightEngine;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
@@ -349,6 +350,7 @@ public class ChunkSerializer {
|
||||
nbttagcompound1.put("TileEntities", nbttaglist1);
|
||||
ListTag nbttaglist2 = new ListTag();
|
||||
|
||||
+ java.util.List<Entity> toUpdate = new java.util.ArrayList<>(); // Paper
|
||||
if (chunk.getStatus().getChunkType() == ChunkStatus.ChunkType.LEVELCHUNK) {
|
||||
LevelChunk chunk1 = (LevelChunk) chunk;
|
||||
|
||||
@@ -366,13 +368,28 @@ public class ChunkSerializer {
|
||||
while (iterator1.hasNext()) {
|
||||
Entity entity = (Entity) iterator1.next();
|
||||
CompoundTag nbttagcompound4 = new CompoundTag();
|
||||
-
|
||||
+ // Paper start
|
||||
+ if ((int) Math.floor(entity.getX()) >> 4 != chunk1.getPos().x || (int) Math.floor(entity.getZ()) >> 4 != chunk1.getPos().z) {
|
||||
+ toUpdate.add(entity);
|
||||
+ continue;
|
||||
+ }
|
||||
+ if (entity.removed || hasPlayerPassenger(entity)) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ // Paper end
|
||||
if (entity.save(nbttagcompound4)) {
|
||||
chunk1.setLastSaveHadEntities(true);
|
||||
nbttaglist2.add(nbttagcompound4);
|
||||
}
|
||||
}
|
||||
}
|
||||
+
|
||||
+ // Paper start - move entities to the correct chunk
|
||||
+ for (Entity entity : toUpdate) {
|
||||
+ world.updateChunkPos(entity);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
} else {
|
||||
ProtoChunk protochunk = (ProtoChunk) chunk;
|
||||
|
||||
@@ -431,6 +448,19 @@ public class ChunkSerializer {
|
||||
nbttagcompound1.put("Structures", packStructureData(chunkcoordintpair, chunk.getAllStarts(), chunk.getAllReferences()));
|
||||
return nbttagcompound;
|
||||
}
|
||||
+ // Paper start - this is saved with the player
|
||||
+ private static boolean hasPlayerPassenger(Entity entity) {
|
||||
+ for (Entity passenger : entity.passengers) {
|
||||
+ if (passenger instanceof ServerPlayer) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ if (hasPlayerPassenger(passenger)) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+ return false;
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
public static ChunkStatus.ChunkType getChunkTypeFromTag(@Nullable CompoundTag tag) {
|
||||
if (tag != null) {
|
|
@ -1,64 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Hugo Manrique <hugmanrique@gmail.com>
|
||||
Date: Thu, 26 Jul 2018 14:10:23 +0200
|
||||
Subject: [PATCH] Don't call getItemMeta on hasItemMeta
|
||||
|
||||
Spigot 1.13 checks if any field (which are manually copied from the ItemStack's "tag" NBT tag) on the ItemMeta class of an ItemStack is set.
|
||||
|
||||
We could just check if the "tag" NBT tag is empty, albeit that would break some plugins. The only general tag added on 1.13 is "Damage", and we can just check if the "tag" NBT tag contains any other tag that's not "Damage" (https://minecraft.gamepedia.com/Player.dat_format#Item_structure) making the `hasItemStack` method behave as before.
|
||||
|
||||
Returns true if getDamage() == 0 or has damage tag or other tag is set.
|
||||
Check the `ItemMetaTest#testTaggedButNotMeta` method to see how this method behaves.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
index 44caf00330e4f4f74745973dbe709980f0b61269..9e06912b0c13c3d61bc95e526acaa28f96b46fb9 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
@@ -569,7 +569,7 @@ public final class CraftItemStack extends ItemStack {
|
||||
|
||||
@Override
|
||||
public boolean hasItemMeta() {
|
||||
- return hasItemMeta(handle) && !CraftItemFactory.instance().equals(getItemMeta(), null);
|
||||
+ return hasItemMeta(handle) && (handle.getDamageValue() != 0 || (handle.getTag() != null && handle.getTag().tags.size() >= (handle.getTag().contains(CraftMetaItem.DAMAGE.NBT) ? 2 : 1))); // Paper - keep 1.12 CraftBukkit behavior without calling getItemMeta
|
||||
}
|
||||
|
||||
static boolean hasItemMeta(net.minecraft.world.item.ItemStack item) {
|
||||
diff --git a/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaTest.java b/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaTest.java
|
||||
index 42f577ed3508ba5a380648461e149f16ce97c9bd..b85a0a4c4f134dd6012d9141244ecf97b4300b65 100644
|
||||
--- a/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaTest.java
|
||||
+++ b/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaTest.java
|
||||
@@ -96,6 +96,34 @@ public class ItemMetaTest extends AbstractTestingBase {
|
||||
assertThat(itemMeta.hasConflictingEnchant(null), is(false));
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ private void testItemMeta(ItemStack stack) {
|
||||
+ assertThat("Should not have ItemMeta", stack.hasItemMeta(), is(false));
|
||||
+
|
||||
+ stack.setDurability((short) 0);
|
||||
+ assertThat("ItemStack with zero durability should not have ItemMeta", stack.hasItemMeta(), is(false));
|
||||
+
|
||||
+ stack.setDurability((short) 2);
|
||||
+ assertThat("ItemStack with non-zero durability should have ItemMeta", stack.hasItemMeta(), is(true));
|
||||
+
|
||||
+ stack.setLore(java.util.Collections.singletonList("Lore"));
|
||||
+ assertThat("ItemStack with lore and durability should have ItemMeta", stack.hasItemMeta(), is(true));
|
||||
+
|
||||
+ stack.setDurability((short) 0);
|
||||
+ assertThat("ItemStack with lore should have ItemMeta", stack.hasItemMeta(), is(true));
|
||||
+
|
||||
+ stack.setLore(null);
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testHasItemMeta() {
|
||||
+ ItemStack itemStack = new ItemStack(Material.SHEARS);
|
||||
+
|
||||
+ testItemMeta(itemStack);
|
||||
+ testItemMeta(CraftItemStack.asCraftCopy(itemStack));
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Test
|
||||
public void testConflictingStoredEnchantment() {
|
||||
EnchantmentStorageMeta itemMeta = (EnchantmentStorageMeta) Bukkit.getItemFactory().getItemMeta(Material.ENCHANTED_BOOK);
|
|
@ -1,120 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sat, 28 Jul 2018 12:18:27 -0400
|
||||
Subject: [PATCH] Ignore Dead Entities in entityList iteration
|
||||
|
||||
A spigot change delays removal of entities from the entity list.
|
||||
This causes a change in behavior from Vanilla where getEntities type
|
||||
methods will return dead entities that they shouldn't otherwise be doing.
|
||||
|
||||
This will ensure that dead entities are skipped from iteration since
|
||||
they shouldn't of been in the list in the first place.
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperCommand.java b/src/main/java/com/destroystokyo/paper/PaperCommand.java
|
||||
index e95b91cefb0374bd5bb57cc090f5ecd566d7a618..8fd716bf2e1402694798b8be03fd85821153be44 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperCommand.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperCommand.java
|
||||
@@ -209,6 +209,7 @@ public class PaperCommand extends Command {
|
||||
Collection<Entity> entities = world.entitiesById.values();
|
||||
entities.forEach(e -> {
|
||||
ResourceLocation key = e.getMinecraftKey();
|
||||
+ if (e.shouldBeRemoved) return; // Paper
|
||||
|
||||
MutablePair<Integer, Map<ChunkPos, Integer>> info = list.computeIfAbsent(key, k -> MutablePair.of(0, Maps.newHashMap()));
|
||||
ChunkPos chunk = new ChunkPos(e.xChunk, e.zChunk);
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
index 8e8e5f30c512ed7d8ee987550c22d3e9df845043..84b2cd661697545186677ab7966556d9288c650b 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -1303,6 +1303,7 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
|
||||
entity.origin = entity.getBukkitEntity().getLocation();
|
||||
}
|
||||
// Paper end
|
||||
+ entity.shouldBeRemoved = false; // Paper - shouldn't be removed after being re-added
|
||||
new com.destroystokyo.paper.event.entity.EntityAddToWorldEvent(entity.getBukkitEntity()).callEvent(); // Paper - fire while valid
|
||||
}
|
||||
|
||||
@@ -1315,6 +1316,7 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
|
||||
this.removeFromChunk(entity);
|
||||
this.entitiesById.remove(entity.getId());
|
||||
this.onEntityRemoved(entity);
|
||||
+ entity.shouldBeRemoved = true; // Paper
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
index 7847078c54154e28ab066ea8a329f929df1e1a37..5bf6bc6a01ccde8a4d67b49293bb326cb09248d8 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -275,6 +275,7 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s
|
||||
protected int numCollisions = 0; // Paper
|
||||
public void inactiveTick() { }
|
||||
// Spigot end
|
||||
+ public boolean shouldBeRemoved; // Paper
|
||||
|
||||
public float getBukkitYaw() {
|
||||
return this.yRot;
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
index 09aa608bd303b618ae2c0ebd237bcbdba60a37a8..db28bfe95c885cdefa855c7aaa3bcf92bc52df26 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
@@ -862,6 +862,7 @@ public class LevelChunk implements ChunkAccess {
|
||||
|
||||
for (int i1 = 0; i1 < l; ++i1) {
|
||||
Entity entity1 = (Entity) list1.get(i1);
|
||||
+ if (entity1.shouldBeRemoved) continue; // Paper
|
||||
|
||||
if (entity1.getBoundingBox().intersects(box) && entity1 != except) {
|
||||
if (predicate == null || predicate.test(entity1)) {
|
||||
@@ -899,6 +900,7 @@ public class LevelChunk implements ChunkAccess {
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
T entity = (T) iterator.next(); // CraftBukkit - decompile error
|
||||
+ if (entity.shouldBeRemoved) continue; // Paper
|
||||
|
||||
if ((type == null || entity.getType() == type) && entity.getBoundingBox().intersects(box) && predicate.test(entity)) {
|
||||
result.add(entity);
|
||||
@@ -921,6 +923,7 @@ public class LevelChunk implements ChunkAccess {
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
T t0 = (T) iterator.next(); // CraftBukkit - decompile error
|
||||
+ if (t0.shouldBeRemoved) continue; // Paper
|
||||
|
||||
if (entityClass.isInstance(t0) && t0.getBoundingBox().intersects(box) && (predicate == null || predicate.test(t0))) { // Spigot - instance check
|
||||
result.add(t0);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
index 3a3466cd9bbd34dbc0b79567f5579e84a81d6009..9807612aed6c4393cbe1f4b6078e45bf1ba3deb2 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
@@ -1022,6 +1022,7 @@ public class CraftWorld implements World {
|
||||
for (Object o : world.entitiesById.values()) {
|
||||
if (o instanceof net.minecraft.world.entity.Entity) {
|
||||
net.minecraft.world.entity.Entity mcEnt = (net.minecraft.world.entity.Entity) o;
|
||||
+ if (mcEnt.shouldBeRemoved) continue; // Paper
|
||||
Entity bukkitEntity = mcEnt.getBukkitEntity();
|
||||
|
||||
// Assuming that bukkitEntity isn't null
|
||||
@@ -1041,6 +1042,7 @@ public class CraftWorld implements World {
|
||||
for (Object o : world.entitiesById.values()) {
|
||||
if (o instanceof net.minecraft.world.entity.Entity) {
|
||||
net.minecraft.world.entity.Entity mcEnt = (net.minecraft.world.entity.Entity) o;
|
||||
+ if (mcEnt.shouldBeRemoved) continue; // Paper
|
||||
Entity bukkitEntity = mcEnt.getBukkitEntity();
|
||||
|
||||
// Assuming that bukkitEntity isn't null
|
||||
@@ -1067,6 +1069,7 @@ public class CraftWorld implements World {
|
||||
|
||||
for (Object entity: world.entitiesById.values()) {
|
||||
if (entity instanceof net.minecraft.world.entity.Entity) {
|
||||
+ if (((net.minecraft.world.entity.Entity) entity).shouldBeRemoved) continue; // Paper
|
||||
Entity bukkitEntity = ((net.minecraft.world.entity.Entity) entity).getBukkitEntity();
|
||||
|
||||
if (bukkitEntity == null) {
|
||||
@@ -1090,6 +1093,7 @@ public class CraftWorld implements World {
|
||||
|
||||
for (Object entity: world.entitiesById.values()) {
|
||||
if (entity instanceof net.minecraft.world.entity.Entity) {
|
||||
+ if (((net.minecraft.world.entity.Entity) entity).shouldBeRemoved) continue; // Paper
|
||||
Entity bukkitEntity = ((net.minecraft.world.entity.Entity) entity).getBukkitEntity();
|
||||
|
||||
if (bukkitEntity == null) {
|
|
@ -1,104 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: willies952002 <admin@domnian.com>
|
||||
Date: Thu, 26 Jul 2018 02:25:46 -0400
|
||||
Subject: [PATCH] Implement Expanded ArmorStand API
|
||||
|
||||
Add the following:
|
||||
- Add proper methods for getting and setting items in both hands. Deprecates old methods
|
||||
- Enable/Disable slot interactions
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
index 7fc69adc8afa971ee3cf815c6002628ae2149a5b..06e52a0c5decf717e35c605d6bcb46c3c7b29656 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
@@ -426,6 +426,7 @@ public class ArmorStand extends LivingEntity {
|
||||
return enumitemslot;
|
||||
}
|
||||
|
||||
+ public final boolean isSlotDisabled(net.minecraft.world.entity.EquipmentSlot slot) { return this.isDisabled(slot); } // Paper - OBFHELPER
|
||||
private boolean isDisabled(net.minecraft.world.entity.EquipmentSlot slot) {
|
||||
return (this.disabledSlots & 1 << slot.getFilterFlag()) != 0 || slot.getType() == net.minecraft.world.entity.EquipmentSlot.Type.HAND && !this.isShowArms();
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java
|
||||
index 16f996d505b96da8a40c7709214ebbd2a0d0d9f3..d4da5214a39b718671dcaf687cb0ff8668ce9728 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java
|
||||
@@ -238,5 +238,78 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand {
|
||||
public void setCanMove(boolean move) {
|
||||
getHandle().canMove = move;
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public ItemStack getItem(org.bukkit.inventory.EquipmentSlot slot) {
|
||||
+ com.google.common.base.Preconditions.checkNotNull(slot, "slot");
|
||||
+ return getHandle().getItemBySlot(org.bukkit.craftbukkit.CraftEquipmentSlot.getNMS(slot)).asBukkitMirror();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setItem(org.bukkit.inventory.EquipmentSlot slot, ItemStack item) {
|
||||
+ com.google.common.base.Preconditions.checkNotNull(slot, "slot");
|
||||
+ switch (slot) {
|
||||
+ case HAND:
|
||||
+ getEquipment().setItemInMainHand(item);
|
||||
+ return;
|
||||
+ case OFF_HAND:
|
||||
+ getEquipment().setItemInOffHand(item);
|
||||
+ return;
|
||||
+ case FEET:
|
||||
+ setBoots(item);
|
||||
+ return;
|
||||
+ case LEGS:
|
||||
+ setLeggings(item);
|
||||
+ return;
|
||||
+ case CHEST:
|
||||
+ setChestplate(item);
|
||||
+ return;
|
||||
+ case HEAD:
|
||||
+ setHelmet(item);
|
||||
+ return;
|
||||
+ }
|
||||
+ throw new UnsupportedOperationException(slot.name());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public java.util.Set<org.bukkit.inventory.EquipmentSlot> getDisabledSlots() {
|
||||
+ java.util.Set<org.bukkit.inventory.EquipmentSlot> disabled = new java.util.HashSet<>();
|
||||
+ for (org.bukkit.inventory.EquipmentSlot slot : org.bukkit.inventory.EquipmentSlot.values()) {
|
||||
+ if (this.isSlotDisabled(slot)) {
|
||||
+ disabled.add(slot);
|
||||
+ }
|
||||
+ }
|
||||
+ return disabled;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setDisabledSlots(org.bukkit.inventory.EquipmentSlot... slots) {
|
||||
+ int disabled = 0;
|
||||
+ for (org.bukkit.inventory.EquipmentSlot slot : slots) {
|
||||
+ if (slot == org.bukkit.inventory.EquipmentSlot.OFF_HAND) continue;
|
||||
+ net.minecraft.world.entity.EquipmentSlot nmsSlot = org.bukkit.craftbukkit.CraftEquipmentSlot.getNMS(slot);
|
||||
+ disabled += (1 << nmsSlot.getFilterFlag()) + (1 << (nmsSlot.getFilterFlag() + 8)) + (1 << (nmsSlot.getFilterFlag() + 16));
|
||||
+ }
|
||||
+ getHandle().disabledSlots = disabled;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void addDisabledSlots(org.bukkit.inventory.EquipmentSlot... slots) {
|
||||
+ java.util.Set<org.bukkit.inventory.EquipmentSlot> disabled = getDisabledSlots();
|
||||
+ java.util.Collections.addAll(disabled, slots);
|
||||
+ setDisabledSlots(disabled.toArray(new org.bukkit.inventory.EquipmentSlot[0]));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void removeDisabledSlots(org.bukkit.inventory.EquipmentSlot... slots) {
|
||||
+ java.util.Set<org.bukkit.inventory.EquipmentSlot> disabled = getDisabledSlots();
|
||||
+ for (final org.bukkit.inventory.EquipmentSlot slot : slots) disabled.remove(slot);
|
||||
+ setDisabledSlots(disabled.toArray(new org.bukkit.inventory.EquipmentSlot[0]));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isSlotDisabled(org.bukkit.inventory.EquipmentSlot slot) {
|
||||
+ return getHandle().isSlotDisabled(org.bukkit.craftbukkit.CraftEquipmentSlot.getNMS(slot));
|
||||
+ }
|
||||
// Paper end
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Fri, 20 Jul 2018 23:37:03 -0500
|
||||
Subject: [PATCH] AnvilDamageEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/inventory/AnvilMenu.java b/src/main/java/net/minecraft/world/inventory/AnvilMenu.java
|
||||
index aa4b03dc9a0d6b3f387f081a1887672b90c60ef9..3d53edae7e3d5bb00913384ad0eb67551a65750e 100644
|
||||
--- a/src/main/java/net/minecraft/world/inventory/AnvilMenu.java
|
||||
+++ b/src/main/java/net/minecraft/world/inventory/AnvilMenu.java
|
||||
@@ -80,7 +80,16 @@ public class AnvilMenu extends ItemCombinerMenu {
|
||||
|
||||
if (!player.abilities.instabuild && iblockdata.is((Tag) BlockTags.ANVIL) && player.getRandom().nextFloat() < 0.12F) {
|
||||
BlockState iblockdata1 = AnvilBlock.damage(iblockdata);
|
||||
-
|
||||
+ // Paper start
|
||||
+ com.destroystokyo.paper.event.block.AnvilDamagedEvent event = new com.destroystokyo.paper.event.block.AnvilDamagedEvent(getBukkitView(), iblockdata1 != null ? org.bukkit.craftbukkit.block.data.CraftBlockData.fromData(iblockdata1) : null);
|
||||
+ if (!event.callEvent()) {
|
||||
+ return;
|
||||
+ } else if (event.getDamageState() == com.destroystokyo.paper.event.block.AnvilDamagedEvent.DamageState.BROKEN) {
|
||||
+ iblockdata1 = null;
|
||||
+ } else {
|
||||
+ iblockdata1 = ((org.bukkit.craftbukkit.block.data.CraftBlockData) event.getDamageState().getMaterial().createBlockData()).getState().setValue(AnvilBlock.FACING, iblockdata.getValue(AnvilBlock.FACING));
|
||||
+ }
|
||||
+ // Paper end
|
||||
if (iblockdata1 == null) {
|
||||
world.removeBlock(blockposition, false);
|
||||
world.levelEvent(1029, blockposition, 0);
|
|
@ -1,148 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Vainomaa <mikroskeem@mikroskeem.eu>
|
||||
Date: Mon, 16 Jul 2018 00:05:05 +0300
|
||||
Subject: [PATCH] Add TNTPrimeEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java
|
||||
index ae3cf71f14526e1f356216dfaa899c8f5083d46d..37a9e9df7f7f816c214c37e545288bf9329626ed 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java
|
||||
@@ -61,6 +61,7 @@ import org.bukkit.craftbukkit.block.CraftBlock;
|
||||
import org.bukkit.event.entity.EntityExplodeEvent;
|
||||
import org.bukkit.event.entity.EntityRegainHealthEvent;
|
||||
// CraftBukkit end
|
||||
+import com.destroystokyo.paper.event.block.TNTPrimeEvent; // Paper - TNTPrimeEvent
|
||||
|
||||
public class EnderDragon extends Mob implements Enemy {
|
||||
|
||||
@@ -515,6 +516,11 @@ public class EnderDragon extends Mob implements Enemy {
|
||||
});
|
||||
craftBlock.getNMS().spawnAfterBreak((ServerLevel) level, blockposition, ItemStack.EMPTY);
|
||||
}
|
||||
+ // Paper start - TNTPrimeEvent
|
||||
+ org.bukkit.block.Block tntBlock = level.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ());
|
||||
+ if(!new TNTPrimeEvent(tntBlock, TNTPrimeEvent.PrimeReason.EXPLOSION, explosionSource.getSourceMob().getBukkitEntity()).callEvent())
|
||||
+ continue;
|
||||
+ // Paper end
|
||||
nmsBlock.wasExploded(level, blockposition, explosionSource);
|
||||
|
||||
this.level.removeBlock(blockposition, false);
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/FireBlock.java b/src/main/java/net/minecraft/world/level/block/FireBlock.java
|
||||
index 85170008de6e77cfb8e4f55ae440a8428d868af4..31b6c1333c7d0af28385e804e94348cef398748b 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/FireBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/FireBlock.java
|
||||
@@ -3,6 +3,7 @@ package net.minecraft.world.level.block;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||
+import com.destroystokyo.paper.event.block.TNTPrimeEvent; // Paper - TNTPrimeEvent
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.function.Function;
|
||||
@@ -11,6 +12,7 @@ import net.minecraft.Util;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.Vec3i;
|
||||
+import net.minecraft.server.MCUtil;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.item.context.BlockPlaceContext;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
@@ -288,7 +290,7 @@ public class FireBlock extends BaseFireBlock {
|
||||
|
||||
world.setBlock(blockposition, this.getStateWithAge(world, blockposition, l), 3);
|
||||
} else {
|
||||
- world.removeBlock(blockposition, false);
|
||||
+ if(iblockdata.getBlock() != Blocks.TNT) world.removeBlock(blockposition, false); // Paper - TNTPrimeEvent - We might be cancelling it below, move the setAir down
|
||||
}
|
||||
|
||||
Block block = iblockdata.getBlock();
|
||||
@@ -296,6 +298,13 @@ public class FireBlock extends BaseFireBlock {
|
||||
if (block instanceof TntBlock) {
|
||||
TntBlock blocktnt = (TntBlock) block;
|
||||
|
||||
+ // Paper start - TNTPrimeEvent
|
||||
+ org.bukkit.block.Block tntBlock = MCUtil.toBukkitBlock(world, blockposition);
|
||||
+ if (!new TNTPrimeEvent(tntBlock, TNTPrimeEvent.PrimeReason.FIRE, null).callEvent()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ world.setAir(blockposition, false);
|
||||
+ // Paper end
|
||||
TntBlock.explode(world, blockposition);
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/TntBlock.java b/src/main/java/net/minecraft/world/level/block/TntBlock.java
|
||||
index 5c06e2f69f6c0a03f12fab6accc5f9a79ae37118..76665be4b3f2e2821c35d3d6d6407c4da4f224e7 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/TntBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/TntBlock.java
|
||||
@@ -22,6 +22,7 @@ import net.minecraft.world.level.block.state.StateDefinition;
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||
import net.minecraft.world.level.block.state.properties.BooleanProperty;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
+import com.destroystokyo.paper.event.block.TNTPrimeEvent; // Paper - TNTPrimeEvent
|
||||
|
||||
public class TntBlock extends Block {
|
||||
|
||||
@@ -36,6 +37,11 @@ public class TntBlock extends Block {
|
||||
public void onPlace(BlockState state, Level world, BlockPos pos, BlockState oldState, boolean notify) {
|
||||
if (!oldState.is(state.getBlock())) {
|
||||
if (world.hasNeighborSignal(pos)) {
|
||||
+ // Paper start - TNTPrimeEvent
|
||||
+ org.bukkit.block.Block tntBlock = net.minecraft.server.MCUtil.toBukkitBlock(world, pos);;
|
||||
+ if(!new TNTPrimeEvent(tntBlock, TNTPrimeEvent.PrimeReason.REDSTONE, null).callEvent())
|
||||
+ return;
|
||||
+ // Paper end
|
||||
explode(world, pos);
|
||||
world.removeBlock(pos, false);
|
||||
}
|
||||
@@ -46,6 +52,11 @@ public class TntBlock extends Block {
|
||||
@Override
|
||||
public void neighborChanged(BlockState state, Level world, BlockPos pos, Block block, BlockPos fromPos, boolean notify) {
|
||||
if (world.hasNeighborSignal(pos)) {
|
||||
+ // Paper start - TNTPrimeEvent
|
||||
+ org.bukkit.block.Block tntBlock = net.minecraft.server.MCUtil.toBukkitBlock(world, pos);;
|
||||
+ if(!new TNTPrimeEvent(tntBlock, TNTPrimeEvent.PrimeReason.REDSTONE, null).callEvent())
|
||||
+ return;
|
||||
+ // Paper end
|
||||
explode(world, pos);
|
||||
world.removeBlock(pos, false);
|
||||
}
|
||||
@@ -64,6 +75,12 @@ public class TntBlock extends Block {
|
||||
@Override
|
||||
public void wasExploded(Level world, BlockPos pos, Explosion explosion) {
|
||||
if (!world.isClientSide) {
|
||||
+ // Paper start - TNTPrimeEvent
|
||||
+ org.bukkit.block.Block tntBlock = net.minecraft.server.MCUtil.toBukkitBlock(world, pos);
|
||||
+ org.bukkit.entity.Entity source = explosion.source != null ? explosion.source.getBukkitEntity() : null;
|
||||
+ if(!new TNTPrimeEvent(tntBlock, TNTPrimeEvent.PrimeReason.EXPLOSION, source).callEvent())
|
||||
+ return;
|
||||
+ // Paper end
|
||||
PrimedTnt entitytntprimed = new PrimedTnt(world, (double) pos.getX() + 0.5D, (double) pos.getY(), (double) pos.getZ() + 0.5D, explosion.getSourceMob());
|
||||
|
||||
entitytntprimed.setFuse((short) (world.random.nextInt(entitytntprimed.getLife() / 4) + entitytntprimed.getLife() / 8));
|
||||
@@ -92,6 +109,11 @@ public class TntBlock extends Block {
|
||||
if (item != Items.FLINT_AND_STEEL && item != Items.FIRE_CHARGE) {
|
||||
return super.use(state, world, pos, player, hand, hit);
|
||||
} else {
|
||||
+ // Paper start - TNTPrimeEvent
|
||||
+ org.bukkit.block.Block tntBlock = net.minecraft.server.MCUtil.toBukkitBlock(world, pos);
|
||||
+ if(!new TNTPrimeEvent(tntBlock, TNTPrimeEvent.PrimeReason.ITEM, player.getBukkitEntity()).callEvent())
|
||||
+ return InteractionResult.FAIL;
|
||||
+ // Paper end
|
||||
explode(world, pos, (LivingEntity) player);
|
||||
world.setBlock(pos, Blocks.AIR.defaultBlockState(), 11);
|
||||
if (!player.isCreative()) {
|
||||
@@ -121,6 +143,13 @@ public class TntBlock extends Block {
|
||||
}
|
||||
// CraftBukkit end
|
||||
|
||||
+ // Paper start - TNTPrimeEvent
|
||||
+ org.bukkit.block.Block tntBlock = net.minecraft.server.MCUtil.toBukkitBlock(world, blockposition);
|
||||
+ if (!new TNTPrimeEvent(tntBlock, TNTPrimeEvent.PrimeReason.PROJECTILE, projectile.getBukkitEntity()).callEvent()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
explode(world, blockposition, entity instanceof LivingEntity ? (LivingEntity) entity : null);
|
||||
world.removeBlock(blockposition, false);
|
||||
}
|
|
@ -1,75 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shane Freeder <theboyetronic@gmail.com>
|
||||
Date: Sun, 29 Jul 2018 05:02:15 +0100
|
||||
Subject: [PATCH] Break up and make tab spam limits configurable
|
||||
|
||||
Due to the changes in 1.13, clients will send a tab completion request
|
||||
for all bukkit commands in order to factor in the lack of support for
|
||||
brigadier and provide backwards support in the API.
|
||||
|
||||
Craftbukkit, however; has moved the chat spam limiter to also interact
|
||||
with the tab completion request, which while good for avoiding abuse,
|
||||
causes 1.13 clients to easilly be kicked from a server in bukkit due
|
||||
to this. Removing the spam limit could cause issues for servers, however,
|
||||
there is no way for servers to manipulate this without blindly cancelling
|
||||
kick events, which only causes additional complications. This also causes
|
||||
issues in that the tab spam limit and chat share the same field but different
|
||||
limits, meaning that a player having typed a long command may be kicked from
|
||||
the server.
|
||||
|
||||
Splitting the field up and making it configurable allows for server owners
|
||||
to take the burden of this into their own hand without having to rely on
|
||||
plugins doing unsafe things.
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
||||
index 77a03abd59db4a43f6f2d59d4c7ef176e782f205..bd508025b771424c942fd856c31d520b6f548082 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
||||
@@ -296,4 +296,18 @@ public class PaperConfig {
|
||||
Bukkit.getLogger().log(Level.INFO, "Using Aikar's Alternative Luck Formula to apply Luck attribute to all loot pool calculations. See https://luckformula.emc.gs");
|
||||
}
|
||||
}
|
||||
+
|
||||
+ public static int tabSpamIncrement = 1;
|
||||
+ public static int tabSpamLimit = 500;
|
||||
+ private static void tabSpamLimiters() {
|
||||
+ tabSpamIncrement = getInt("settings.spam-limiter.tab-spam-increment", tabSpamIncrement);
|
||||
+ // Older versions used a smaller limit, which is too low for 1.13, we'll bump this up if default
|
||||
+ if (version < 14) {
|
||||
+ if (tabSpamIncrement == 10) {
|
||||
+ set("settings.spam-limiter.tab-spam-increment", 2);
|
||||
+ tabSpamIncrement = 2;
|
||||
+ }
|
||||
+ }
|
||||
+ tabSpamLimit = getInt("settings.spam-limiter.tab-spam-limit", tabSpamLimit);
|
||||
+ }
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 645f7b7c862acf77d70ca0b05308945424bc4d32..900c9b1106a153bc386f6c3d9c11226f8ac69f86 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -228,6 +228,7 @@ public class ServerGamePacketListenerImpl implements ServerGamePacketListener {
|
||||
// CraftBukkit start - multithreaded fields
|
||||
private volatile int chatSpamTickCount;
|
||||
private static final AtomicIntegerFieldUpdater chatSpamField = AtomicIntegerFieldUpdater.newUpdater(ServerGamePacketListenerImpl.class, "chatThrottle");
|
||||
+ private final java.util.concurrent.atomic.AtomicInteger tabSpamLimiter = new java.util.concurrent.atomic.AtomicInteger(); // Paper - configurable tab spam limits
|
||||
// CraftBukkit end
|
||||
private int dropSpamTickCount;
|
||||
private final Int2ShortMap expectedAcks = new Int2ShortOpenHashMap();
|
||||
@@ -363,6 +364,7 @@ public class ServerGamePacketListenerImpl implements ServerGamePacketListener {
|
||||
this.server.getProfiler().pop();
|
||||
// CraftBukkit start
|
||||
for (int spam; (spam = this.chatSpamTickCount) > 0 && !chatSpamField.compareAndSet(this, spam, spam - 1); ) ;
|
||||
+ if (tabSpamLimiter.get() > 0) tabSpamLimiter.getAndDecrement(); // Paper - split to seperate variable
|
||||
/* Use thread-safe field access instead
|
||||
if (this.chatThrottle > 0) {
|
||||
--this.chatThrottle;
|
||||
@@ -714,7 +716,7 @@ public class ServerGamePacketListenerImpl implements ServerGamePacketListener {
|
||||
public void handleCustomCommandSuggestions(ServerboundCommandSuggestionPacket packet) {
|
||||
// PlayerConnectionUtils.ensureMainThread(packetplayintabcomplete, this, this.player.getWorldServer()); // Paper - run this async
|
||||
// CraftBukkit start
|
||||
- if (chatSpamField.addAndGet(this, 1) > 500 && !this.server.getPlayerList().isOp(this.player.getGameProfile())) {
|
||||
+ if (tabSpamLimiter.addAndGet(com.destroystokyo.paper.PaperConfig.tabSpamIncrement) > com.destroystokyo.paper.PaperConfig.tabSpamLimit && !this.server.getPlayerList().isOp(this.player.getGameProfile())) { // Paper start - split and make configurable
|
||||
server.scheduleOnMain(() -> this.disconnect(new TranslatableComponent("disconnect.spam", new Object[0]))); // Paper
|
||||
return;
|
||||
}
|
|
@ -1,341 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Thu, 2 Aug 2018 08:44:35 -0500
|
||||
Subject: [PATCH] Add hand to bucket events
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index d34da1eb172a7dcda564680afecf3dc145bf09f3..125a75576442eaa4f1ff6dd153bdb31097497a3f 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -724,7 +724,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
// CraftBukkit end
|
||||
|
||||
MinecraftServer.LOGGER.info("Preparing start region for dimension {}", worldserver.dimension().location());
|
||||
- BlockPos blockposition = worldserver.getSharedSpawnPos();
|
||||
+ BlockPos blockposition = worldserver.getSpawn();
|
||||
|
||||
worldloadlistener.updateSpawnPos(new ChunkPos(blockposition));
|
||||
ServerChunkCache chunkproviderserver = worldserver.getChunkSource();
|
||||
@@ -1897,7 +1897,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
public CommandSourceStack createCommandSourceStack() {
|
||||
ServerLevel worldserver = this.overworld();
|
||||
|
||||
- return new CommandSourceStack(this, worldserver == null ? Vec3.ZERO : Vec3.atLowerCornerOf((Vec3i) worldserver.getSharedSpawnPos()), Vec2.ZERO, worldserver, 4, "Server", new TextComponent("Server"), this, (Entity) null);
|
||||
+ return new CommandSourceStack(this, worldserver == null ? Vec3.ZERO : Vec3.atLowerCornerOf((Vec3i) worldserver.getSpawn()), Vec2.ZERO, worldserver, 4, "Server", new TextComponent("Server"), this, (Entity) null);
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
index 883e05ba87c3bdec9a0d4bbd035b90c795448239..9143fe99e43236bf65e6f098a30d522302ad78b7 100644
|
||||
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
@@ -526,7 +526,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
|
||||
} else if (this.getSpawnProtectionRadius() <= 0) {
|
||||
return false;
|
||||
} else {
|
||||
- BlockPos blockposition1 = world.getSharedSpawnPos();
|
||||
+ BlockPos blockposition1 = world.getSpawn();
|
||||
int i = Mth.abs(pos.getX() - blockposition1.getX());
|
||||
int j = Mth.abs(pos.getZ() - blockposition1.getZ());
|
||||
int k = Math.max(i, j);
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
index 84b2cd661697545186677ab7966556d9288c650b..2ab221e5315dde4e556ee49a6962ae0091ccf616 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -1651,15 +1651,17 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
|
||||
this.getServer().getPlayerList().broadcastAll(new ClientboundSetDefaultSpawnPositionPacket(pos, angle));
|
||||
}
|
||||
|
||||
- public BlockPos getSharedSpawnPos() {
|
||||
- BlockPos blockposition = new BlockPos(this.levelData.getXSpawn(), this.levelData.getYSpawn(), this.levelData.getZSpawn());
|
||||
-
|
||||
- if (!this.getWorldBorder().isWithinBounds(blockposition)) {
|
||||
- blockposition = this.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, new BlockPos(this.getWorldBorder().getCenterX(), 0.0D, this.getWorldBorder().getCenterZ()));
|
||||
- }
|
||||
-
|
||||
- return blockposition;
|
||||
- }
|
||||
+ // Paper - moved up to World
|
||||
+ //public BlockPosition getSpawn() {
|
||||
+ // BlockPosition blockposition = new BlockPosition(this.worldData.a(), this.worldData.b(), this.worldData.c());
|
||||
+ //
|
||||
+ // if (!this.getWorldBorder().a(blockposition)) {
|
||||
+ // blockposition = this.getHighestBlockYAt(HeightMap.Type.MOTION_BLOCKING, new BlockPosition(this.getWorldBorder().getCenterX(), 0.0D, this.getWorldBorder().getCenterZ()));
|
||||
+ // }
|
||||
+ //
|
||||
+ // return blockposition;
|
||||
+ //}
|
||||
+ // Paper end
|
||||
|
||||
public float getSharedSpawnAngle() {
|
||||
return this.levelData.getSpawnAngle();
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
index 1441a461e749dbfa303095f6b51d655c45f68ce0..5664e292046d4fcdb81340df8cee8d04aa27ca55 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -231,7 +231,7 @@ public class ServerPlayer extends Player implements ContainerListener {
|
||||
public final com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> cachedSingleHashSet; // Paper
|
||||
|
||||
public ServerPlayer(MinecraftServer server, ServerLevel world, GameProfile profile, ServerPlayerGameMode interactionManager) {
|
||||
- super(world, world.getSharedSpawnPos(), world.getSharedSpawnAngle(), profile);
|
||||
+ super(world, world.getSpawn(), world.getSharedSpawnAngle(), profile);
|
||||
this.respawnDimension = Level.OVERWORLD;
|
||||
interactionManager.player = this;
|
||||
this.gameMode = interactionManager;
|
||||
@@ -254,7 +254,7 @@ public class ServerPlayer extends Player implements ContainerListener {
|
||||
// Yes, this doesn't match Vanilla, but it's the best we can do for now.
|
||||
// If this is an issue, PRs are welcome
|
||||
public final BlockPos getSpawnPoint(ServerLevel worldserver) {
|
||||
- BlockPos blockposition = worldserver.getSharedSpawnPos();
|
||||
+ BlockPos blockposition = worldserver.getSpawn();
|
||||
|
||||
if (worldserver.dimensionType().hasSkyLight() && worldserver.worldDataServer.getGameType() != GameType.ADVENTURE) {
|
||||
int i = Math.max(0, this.server.getSpawnRadius(worldserver));
|
||||
@@ -291,7 +291,7 @@ public class ServerPlayer extends Player implements ContainerListener {
|
||||
// CraftBukkit end
|
||||
|
||||
private void fudgeSpawnLocation(ServerLevel world) {
|
||||
- BlockPos blockposition = world.getSharedSpawnPos();
|
||||
+ BlockPos blockposition = world.getSpawn();
|
||||
|
||||
if (world.dimensionType().hasSkyLight() && world.worldDataServer.getGameType() != GameType.ADVENTURE) { // CraftBukkit
|
||||
int i = Math.max(0, this.server.getSpawnRadius(world));
|
||||
@@ -464,7 +464,7 @@ public class ServerPlayer extends Player implements ContainerListener {
|
||||
}
|
||||
if (world == null || position == null) {
|
||||
world = ((CraftWorld) Bukkit.getServer().getWorlds().get(0)).getHandle();
|
||||
- position = Vec3.atCenterOf(((ServerLevel) world).getSharedSpawnPos());
|
||||
+ position = Vec3.atCenterOf(((ServerLevel) world).getSpawn());
|
||||
}
|
||||
this.level = world;
|
||||
this.setPos(position.x(), position.y(), position.z());
|
||||
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
index 51b1ce465d23b971f7e08a3175319a33183d0398..0bb397407b55bd1c464ac603ec4c189045aabbb2 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
@@ -808,7 +808,7 @@ public abstract class PlayerList {
|
||||
entityplayer1.setShiftKeyDown(false);
|
||||
|
||||
// entityplayer1.playerConnection.a(entityplayer1.locX(), entityplayer1.locY(), entityplayer1.locZ(), entityplayer1.yaw, entityplayer1.pitch);
|
||||
- entityplayer1.connection.send(new ClientboundSetDefaultSpawnPositionPacket(worldserver1.getSharedSpawnPos(), worldserver1.getSharedSpawnAngle()));
|
||||
+ entityplayer1.connection.send(new ClientboundSetDefaultSpawnPositionPacket(worldserver1.getSpawn(), worldserver1.getSharedSpawnAngle()));
|
||||
entityplayer1.connection.send(new ClientboundChangeDifficultyPacket(worlddata.getDifficulty(), worlddata.isDifficultyLocked()));
|
||||
entityplayer1.connection.send(new ClientboundSetExperiencePacket(entityplayer1.experienceProgress, entityplayer1.totalExperience, entityplayer1.experienceLevel));
|
||||
this.sendLevelInfo(entityplayer1, worldserver1);
|
||||
@@ -1090,7 +1090,7 @@ public abstract class PlayerList {
|
||||
|
||||
player.connection.send(new ClientboundSetBorderPacket(worldborder, ClientboundSetBorderPacket.Type.INITIALIZE));
|
||||
player.connection.send(new ClientboundSetTimePacket(world.getGameTime(), world.getDayTime(), world.getGameRules().getBoolean(GameRules.RULE_DAYLIGHT)));
|
||||
- player.connection.send(new ClientboundSetDefaultSpawnPositionPacket(world.getSharedSpawnPos(), world.getSharedSpawnAngle()));
|
||||
+ player.connection.send(new ClientboundSetDefaultSpawnPositionPacket(world.getSpawn(), world.getSharedSpawnAngle()));
|
||||
if (world.isRaining()) {
|
||||
// CraftBukkit start - handle player weather
|
||||
// entityplayer.playerConnection.sendPacket(new PacketPlayOutGameStateChange(PacketPlayOutGameStateChange.b, 0.0F));
|
||||
diff --git a/src/main/java/net/minecraft/server/rcon/RconConsoleSource.java b/src/main/java/net/minecraft/server/rcon/RconConsoleSource.java
|
||||
index c283ea9528493fb95088870c84c6d6e3963aabb7..2633aca30601682a53b0236b94a12f0f18a87fc2 100644
|
||||
--- a/src/main/java/net/minecraft/server/rcon/RconConsoleSource.java
|
||||
+++ b/src/main/java/net/minecraft/server/rcon/RconConsoleSource.java
|
||||
@@ -33,7 +33,7 @@ public class RconConsoleSource implements CommandSource {
|
||||
public CommandSourceStack createCommandSourceStack() {
|
||||
ServerLevel worldserver = this.server.overworld();
|
||||
|
||||
- return new CommandSourceStack(this, Vec3.atLowerCornerOf((Vec3i) worldserver.getSharedSpawnPos()), Vec2.ZERO, worldserver, 4, "Rcon", RconConsoleSource.RCON_COMPONENT, this.server, (Entity) null);
|
||||
+ return new CommandSourceStack(this, Vec3.atLowerCornerOf((Vec3i) worldserver.getSpawn()), Vec2.ZERO, worldserver, 4, "Rcon", RconConsoleSource.RCON_COMPONENT, this.server, (Entity) null);
|
||||
}
|
||||
|
||||
// CraftBukkit start - Send a String
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
index 5bf6bc6a01ccde8a4d67b49293bb326cb09248d8..4503bd65b3454bad94bb7b869f4e72e3121d8a3d 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -2688,7 +2688,7 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s
|
||||
if (flag1) {
|
||||
blockposition1 = ServerLevel.END_SPAWN_POINT;
|
||||
} else {
|
||||
- blockposition1 = destination.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, destination.getSharedSpawnPos());
|
||||
+ blockposition1 = destination.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, destination.getSpawn());
|
||||
}
|
||||
// CraftBukkit start
|
||||
CraftPortalEvent event = callPortalEvent(this, destination, blockposition1, PlayerTeleportEvent.TeleportCause.END_PORTAL, 0, 0);
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/Cow.java b/src/main/java/net/minecraft/world/entity/animal/Cow.java
|
||||
index 90393bb196c0895f387259c2dccbb29e2ca11c87..9c67b603d4d0ee5cb7f86b25ed8754afaf9cf7b3 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/Cow.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/Cow.java
|
||||
@@ -87,7 +87,7 @@ public class Cow extends Animal {
|
||||
|
||||
if (itemstack.getItem() == Items.BUCKET && !this.isBaby()) {
|
||||
// CraftBukkit start - Got milk?
|
||||
- org.bukkit.event.player.PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((ServerLevel) player.level, player, this.blockPosition(), this.blockPosition(), null, itemstack, Items.MILK_BUCKET);
|
||||
+ org.bukkit.event.player.PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((ServerLevel) player.level, player, this.blockPosition(), this.blockPosition(), null, itemstack, Items.MILK_BUCKET, hand); // Paper - add enumHand
|
||||
|
||||
if (event.isCancelled()) {
|
||||
return InteractionResult.PASS;
|
||||
diff --git a/src/main/java/net/minecraft/world/item/BucketItem.java b/src/main/java/net/minecraft/world/item/BucketItem.java
|
||||
index b426e155d13a1b2eb5ddb24a2d83cd7d1e92026b..d0e847e58483695d2af1c1410826bb25231cd6f6 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/BucketItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/BucketItem.java
|
||||
@@ -69,7 +69,7 @@ public class BucketItem extends Item {
|
||||
if (iblockdata.getBlock() instanceof BucketPickup) {
|
||||
// CraftBukkit start
|
||||
Fluid dummyFluid = ((BucketPickup) iblockdata.getBlock()).takeLiquid(DummyGeneratorAccess.INSTANCE, blockposition, iblockdata);
|
||||
- PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((ServerLevel) world, user, blockposition, blockposition, movingobjectpositionblock.getDirection(), itemstack, dummyFluid.getBucket());
|
||||
+ PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((ServerLevel) world, user, blockposition, blockposition, movingobjectpositionblock.getDirection(), itemstack, dummyFluid.getBucket(), hand); // Paper - add enumhand
|
||||
|
||||
if (event.isCancelled()) {
|
||||
((ServerPlayer) user).connection.send(new ClientboundBlockUpdatePacket(world, blockposition)); // SPIGOT-5163 (see PlayerInteractManager)
|
||||
@@ -97,7 +97,7 @@ public class BucketItem extends Item {
|
||||
iblockdata = world.getBlockState(blockposition);
|
||||
BlockPos blockposition2 = iblockdata.getBlock() instanceof LiquidBlockContainer && this.content == Fluids.WATER ? blockposition : blockposition1;
|
||||
|
||||
- if (this.a(user, world, blockposition2, movingobjectpositionblock1, movingobjectpositionblock1.getDirection(), blockposition, itemstack)) { // CraftBukkit
|
||||
+ if (this.a(user, world, blockposition2, movingobjectpositionblock1, movingobjectpositionblock1.getDirection(), blockposition, itemstack, hand)) { // CraftBukkit // Paper - add enumhand
|
||||
this.checkExtraContent(world, itemstack, blockposition2);
|
||||
if (user instanceof ServerPlayer) {
|
||||
CriteriaTriggers.PLACED_BLOCK.trigger((ServerPlayer) user, blockposition2, itemstack);
|
||||
@@ -122,10 +122,12 @@ public class BucketItem extends Item {
|
||||
public void checkExtraContent(Level world, ItemStack stack, BlockPos pos) {}
|
||||
|
||||
public boolean emptyBucket(@Nullable Player player, Level world, BlockPos pos, @Nullable BlockHitResult movingobjectpositionblock) {
|
||||
- return a(player, world, pos, movingobjectpositionblock, null, null, null);
|
||||
+ // Paper start - add enumHand
|
||||
+ return a(player, world, pos, movingobjectpositionblock, null, null, null, null);
|
||||
}
|
||||
|
||||
- public boolean a(Player entityhuman, Level world, BlockPos blockposition, @Nullable BlockHitResult movingobjectpositionblock, Direction enumdirection, BlockPos clicked, ItemStack itemstack) {
|
||||
+ public boolean a(Player entityhuman, Level world, BlockPos blockposition, @Nullable BlockHitResult movingobjectpositionblock, Direction enumdirection, BlockPos clicked, ItemStack itemstack, InteractionHand enumhand) {
|
||||
+ // Paper end
|
||||
// CraftBukkit end
|
||||
if (!(this.content instanceof FlowingFluid)) {
|
||||
return false;
|
||||
@@ -138,7 +140,7 @@ public class BucketItem extends Item {
|
||||
|
||||
// CraftBukkit start
|
||||
if (flag1 && entityhuman != null) {
|
||||
- PlayerBucketEmptyEvent event = CraftEventFactory.callPlayerBucketEmptyEvent((ServerLevel) world, entityhuman, blockposition, clicked, enumdirection, itemstack);
|
||||
+ PlayerBucketEmptyEvent event = CraftEventFactory.callPlayerBucketEmptyEvent((ServerLevel) world, entityhuman, blockposition, clicked, enumdirection, itemstack, enumhand); // Paper - add enumhand
|
||||
if (event.isCancelled()) {
|
||||
((ServerPlayer) entityhuman).connection.send(new ClientboundBlockUpdatePacket(world, blockposition)); // SPIGOT-4238: needed when looking through entity
|
||||
((ServerPlayer) entityhuman).getBukkitEntity().updateInventory(); // SPIGOT-4541
|
||||
@@ -147,7 +149,7 @@ public class BucketItem extends Item {
|
||||
}
|
||||
// CraftBukkit end
|
||||
if (!flag1) {
|
||||
- return movingobjectpositionblock != null && this.a(entityhuman, world, movingobjectpositionblock.getBlockPos().relative(movingobjectpositionblock.getDirection()), (BlockHitResult) null, enumdirection, clicked, itemstack); // CraftBukkit
|
||||
+ return movingobjectpositionblock != null && this.a(entityhuman, world, movingobjectpositionblock.getBlockPos().relative(movingobjectpositionblock.getDirection()), (BlockHitResult) null, enumdirection, clicked, itemstack, enumhand); // CraftBukkit // Paper - add enumhand
|
||||
} else if (world.dimensionType().ultraWarm() && this.content.is((Tag) FluidTags.WATER)) {
|
||||
int i = blockposition.getX();
|
||||
int j = blockposition.getY();
|
||||
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
|
||||
index 7a9ccd203885b9b369767d1fb8c53783201d0f0f..b75ffafb6840b6acab6e5b0ef5e222c4fa130977 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/Level.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
||||
@@ -277,6 +277,17 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
}
|
||||
// Paper end
|
||||
|
||||
+ // Paper start - moved up from WorldServer
|
||||
+ public BlockPos getSpawn() {
|
||||
+ BlockPos blockposition = new BlockPos(this.levelData.getXSpawn(), this.levelData.getYSpawn(), this.levelData.getZSpawn());
|
||||
+
|
||||
+ if (!this.getWorldBorder().isWithinBounds(blockposition)) {
|
||||
+ blockposition = this.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, new BlockPos(this.getWorldBorder().getCenterX(), 0.0D, this.getWorldBorder().getCenterZ()));
|
||||
+ }
|
||||
+
|
||||
+ return blockposition;
|
||||
+ }
|
||||
+ // Paper end
|
||||
@Override
|
||||
public boolean isClientSide() {
|
||||
return this.isClientSide;
|
||||
diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java
|
||||
index 8a71eaf2855be0d415d1f7b18dbec98353fe5b47..b90a275a0dc2913809ce16659eed445501e486de 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java
|
||||
@@ -268,7 +268,7 @@ public final class NaturalSpawner {
|
||||
private static boolean isRightDistanceToPlayerAndSpawnPoint(ServerLevel world, ChunkAccess chunk, BlockPos.MutableBlockPos pos, double squaredDistance) {
|
||||
if (squaredDistance <= 576.0D) {
|
||||
return false;
|
||||
- } else if (world.getSharedSpawnPos().closerThan((Position) (new Vec3((double) pos.getX() + 0.5D, (double) pos.getY(), (double) pos.getZ() + 0.5D)), 24.0D)) {
|
||||
+ } else if (world.getSpawn().closerThan((Position) (new Vec3((double) pos.getX() + 0.5D, (double) pos.getY(), (double) pos.getZ() + 0.5D)), 24.0D)) {
|
||||
return false;
|
||||
} else {
|
||||
ChunkPos chunkcoordintpair = new ChunkPos(pos);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
index 9807612aed6c4393cbe1f4b6078e45bf1ba3deb2..159c32d6678e83f2d98ea6a1ad48346c9de017e1 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
@@ -327,7 +327,7 @@ public class CraftWorld implements World {
|
||||
|
||||
@Override
|
||||
public Location getSpawnLocation() {
|
||||
- BlockPos spawn = world.getSharedSpawnPos();
|
||||
+ BlockPos spawn = world.getSpawn();
|
||||
return new Location(this, spawn.getX(), spawn.getY(), spawn.getZ());
|
||||
}
|
||||
|
||||
@@ -1926,7 +1926,7 @@ public class CraftWorld implements World {
|
||||
public void setKeepSpawnInMemory(boolean keepLoaded) {
|
||||
world.keepSpawnInMemory = keepLoaded;
|
||||
// Grab the worlds spawn chunk
|
||||
- BlockPos chunkcoordinates = this.world.getSharedSpawnPos();
|
||||
+ BlockPos chunkcoordinates = this.world.getSpawn();
|
||||
if (keepLoaded) {
|
||||
world.getChunkSource().addRegionTicket(TicketType.START, new ChunkPos(chunkcoordinates), 11, Unit.INSTANCE);
|
||||
} else {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
index 4cd08821305590e21a01cc4dda05370c2b721ac2..1877267344df1ff5b4de6a4e0c239f488cd52c1f 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
@@ -222,7 +222,7 @@ public class CraftEventFactory {
|
||||
public static Entity entityDamage; // For use in EntityDamageByEntityEvent
|
||||
|
||||
// helper methods
|
||||
- private static boolean canBuild(ServerLevel world, Player player, int x, int z) {
|
||||
+ private static boolean canBuild(Level world, Player player, int x, int z) {
|
||||
int spawnSize = Bukkit.getServer().getSpawnRadius();
|
||||
|
||||
if (world.dimension() != Level.OVERWORLD) return true;
|
||||
@@ -230,7 +230,7 @@ public class CraftEventFactory {
|
||||
if (((CraftServer) Bukkit.getServer()).getHandle().getOps().isEmpty()) return true;
|
||||
if (player.isOp()) return true;
|
||||
|
||||
- BlockPos chunkcoordinates = world.getSharedSpawnPos();
|
||||
+ BlockPos chunkcoordinates = world.getSpawn();
|
||||
|
||||
int distanceFromSpawn = Math.max(Math.abs(x - chunkcoordinates.getX()), Math.abs(z - chunkcoordinates.getZ()));
|
||||
return distanceFromSpawn > spawnSize;
|
||||
@@ -412,6 +412,20 @@ public class CraftEventFactory {
|
||||
}
|
||||
|
||||
private static PlayerEvent getPlayerBucketEvent(boolean isFilling, ServerLevel world, net.minecraft.world.entity.player.Player who, BlockPos changed, BlockPos clicked, Direction clickedFace, ItemStack itemstack, net.minecraft.world.item.Item item) {
|
||||
+ // Paper start - add enumHand
|
||||
+ return getPlayerBucketEvent(isFilling, world, who, changed, clicked, clickedFace, itemstack, item, null);
|
||||
+ }
|
||||
+
|
||||
+ public static PlayerBucketEmptyEvent callPlayerBucketEmptyEvent(Level world, net.minecraft.world.entity.player.Player who, BlockPos changed, BlockPos clicked, Direction clickedFace, ItemStack itemstack, InteractionHand enumHand) {
|
||||
+ return (PlayerBucketEmptyEvent) getPlayerBucketEvent(false, world, who, changed, clicked, clickedFace, itemstack, Items.BUCKET, enumHand);
|
||||
+ }
|
||||
+
|
||||
+ public static PlayerBucketFillEvent callPlayerBucketFillEvent(Level world, net.minecraft.world.entity.player.Player who, BlockPos changed, BlockPos clicked, Direction clickedFace, ItemStack itemInHand, net.minecraft.world.item.Item bucket, InteractionHand enumHand) {
|
||||
+ return (PlayerBucketFillEvent) getPlayerBucketEvent(true, world, who, clicked, changed, clickedFace, itemInHand, bucket, enumHand);
|
||||
+ }
|
||||
+
|
||||
+ private static PlayerEvent getPlayerBucketEvent(boolean isFilling, Level world, net.minecraft.world.entity.player.Player who, BlockPos changed, BlockPos clicked, Direction clickedFace, ItemStack itemstack, net.minecraft.world.item.Item item, InteractionHand enumHand) {
|
||||
+ // Paper end
|
||||
Player player = (Player) who.getBukkitEntity();
|
||||
CraftItemStack itemInHand = CraftItemStack.asNewCraftStack(item);
|
||||
Material bucket = CraftMagicNumbers.getMaterial(itemstack.getItem());
|
||||
@@ -424,10 +438,10 @@ public class CraftEventFactory {
|
||||
|
||||
PlayerEvent event;
|
||||
if (isFilling) {
|
||||
- event = new PlayerBucketFillEvent(player, block, blockClicked, blockFace, bucket, itemInHand);
|
||||
+ event = new PlayerBucketFillEvent(player, block, blockClicked, blockFace, bucket, itemInHand, enumHand == null ? null : enumHand == InteractionHand.OFF_HAND ? EquipmentSlot.OFF_HAND : EquipmentSlot.HAND); // Paper - add enumHand
|
||||
((PlayerBucketFillEvent) event).setCancelled(!canBuild(world, player, changed.getX(), changed.getZ()));
|
||||
} else {
|
||||
- event = new PlayerBucketEmptyEvent(player, block, blockClicked, blockFace, bucket, itemInHand);
|
||||
+ event = new PlayerBucketEmptyEvent(player, block, blockClicked, blockFace, bucket, itemInHand, enumHand == null ? null : enumHand == InteractionHand.OFF_HAND ? EquipmentSlot.OFF_HAND : EquipmentSlot.HAND); // Paper - add enumHand
|
||||
((PlayerBucketEmptyEvent) event).setCancelled(!canBuild(world, player, changed.getX(), changed.getZ()));
|
||||
}
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Fri, 3 Aug 2018 00:04:54 -0400
|
||||
Subject: [PATCH] MC-135506: Experience should save as Integers
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/ExperienceOrb.java b/src/main/java/net/minecraft/world/entity/ExperienceOrb.java
|
||||
index 52b90ef3a145325209d3d903a2b7c9a44c332cbe..37758cff3c4a8406c2f1496ae827ecdc953cf9f4 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ExperienceOrb.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ExperienceOrb.java
|
||||
@@ -217,7 +217,7 @@ public class ExperienceOrb extends Entity {
|
||||
public void addAdditionalSaveData(CompoundTag tag) {
|
||||
tag.putShort("Health", (short) this.health);
|
||||
tag.putShort("Age", (short) this.age);
|
||||
- tag.putShort("Value", (short) this.value);
|
||||
+ tag.putInt("Value", this.value); // Paper - save as Integer
|
||||
this.savePaperNBT(tag); // Paper
|
||||
}
|
||||
|
||||
@@ -225,7 +225,7 @@ public class ExperienceOrb extends Entity {
|
||||
public void readAdditionalSaveData(CompoundTag tag) {
|
||||
this.health = tag.getShort("Health");
|
||||
this.age = tag.getShort("Age");
|
||||
- this.value = tag.getShort("Value");
|
||||
+ this.value = tag.getInt("Value"); // Paper - load as Integer
|
||||
this.loadPaperNBT(tag); // Paper
|
||||
}
|
||||
|
|
@ -1,147 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 22 Nov 2016 00:40:42 -0500
|
||||
Subject: [PATCH] Fix client rendering skulls from same user
|
||||
|
||||
See: https://github.com/PaperMC/Paper/issues/1304
|
||||
|
||||
Changes the UUID sent to client to be based on either
|
||||
the texture payload, or random.
|
||||
|
||||
This allows the client to render multiple skull textures from the same user,
|
||||
for when different skins were used when skull was made.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/network/FriendlyByteBuf.java b/src/main/java/net/minecraft/network/FriendlyByteBuf.java
|
||||
index b4542ce6a8c37ab31e6ecaeb4cbad4742cca0f9b..10f1e3d761af83507bf71a00092641e22d0c8049 100644
|
||||
--- a/src/main/java/net/minecraft/network/FriendlyByteBuf.java
|
||||
+++ b/src/main/java/net/minecraft/network/FriendlyByteBuf.java
|
||||
@@ -37,6 +37,7 @@ import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
+import net.minecraft.world.level.block.entity.SkullBlockEntity;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.bukkit.craftbukkit.inventory.CraftItemStack; // CraftBukkit
|
||||
@@ -310,9 +311,18 @@ public class FriendlyByteBuf extends ByteBuf {
|
||||
if (item.canBeDepleted() || item.shouldOverrideMultiplayerNbt()) {
|
||||
// Spigot start - filter
|
||||
itemstack = itemstack.copy();
|
||||
- CraftItemStack.setItemMeta(itemstack, CraftItemStack.getItemMeta(itemstack));
|
||||
+ //CraftItemStack.setItemMeta(itemstack, CraftItemStack.getItemMeta(itemstack)); // Paper - This is no longer needed due to NBT being supported
|
||||
// Spigot end
|
||||
nbttagcompound = itemstack.getTag();
|
||||
+ // Paper start
|
||||
+ if (nbttagcompound != null && nbttagcompound.contains("SkullOwner", 10)) {
|
||||
+ CompoundTag owner = nbttagcompound.getCompound("SkullOwner");
|
||||
+ if (owner.hasUUID("Id")) {
|
||||
+ nbttagcompound.setUUID("SkullOwnerOrig", owner.getUUID("Id"));
|
||||
+ SkullBlockEntity.sanitizeUUID(owner);
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
this.writeNbt(nbttagcompound);
|
||||
@@ -332,7 +342,16 @@ public class FriendlyByteBuf extends ByteBuf {
|
||||
itemstack.setTag(this.readNbt());
|
||||
// CraftBukkit start
|
||||
if (itemstack.getTag() != null) {
|
||||
- CraftItemStack.setItemMeta(itemstack, CraftItemStack.getItemMeta(itemstack));
|
||||
+ // Paper start - Fix skulls of same owner - restore orig ID since we changed it on send to client
|
||||
+ if (itemstack.tag.contains("SkullOwnerOrig")) {
|
||||
+ CompoundTag owner = itemstack.tag.getCompound("SkullOwner");
|
||||
+ if (itemstack.tag.contains("SkullOwnerOrig")) {
|
||||
+ owner.tags.put("Id", itemstack.tag.tags.get("SkullOwnerOrig"));
|
||||
+ itemstack.tag.remove("SkullOwnerOrig");
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
+ // CraftItemStack.setItemMeta(itemstack, CraftItemStack.getItemMeta(itemstack)); // Paper - This is no longer needed due to NBT being supported
|
||||
}
|
||||
// CraftBukkit end
|
||||
return itemstack;
|
||||
diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkPacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkPacket.java
|
||||
index e5d4363edb8c494d2db69d2e0223a2db1519f64b..4fe15aa331ca18319ca46d1b426f0d6fd24341f0 100644
|
||||
--- a/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkPacket.java
|
||||
+++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkPacket.java
|
||||
@@ -15,6 +15,7 @@ import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
+import net.minecraft.world.level.block.entity.SkullBlockEntity;
|
||||
import net.minecraft.world.level.chunk.ChunkBiomeContainer;
|
||||
import net.minecraft.world.level.chunk.LevelChunk;
|
||||
import net.minecraft.world.level.chunk.LevelChunkSection;
|
||||
@@ -69,6 +70,7 @@ public class ClientboundLevelChunkPacket implements Packet<ClientGamePacketListe
|
||||
|
||||
if (this.isFullChunk() || (includedSectionsMask & 1 << j) != 0) {
|
||||
CompoundTag nbttagcompound = tileentity.getUpdateTag();
|
||||
+ if (tileentity instanceof SkullBlockEntity) { SkullBlockEntity.sanitizeTileEntityUUID(nbttagcompound); } // Paper
|
||||
|
||||
this.blockEntitiesTags.add(nbttagcompound);
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
index 34187197efd5ceff0503682dc6ce313220ca916f..79a7c37f15840dbd97510874ac12437d2b854999 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
@@ -112,7 +112,7 @@ public final class ItemStack {
|
||||
private int popTime;
|
||||
@Deprecated
|
||||
private Item item;
|
||||
- private CompoundTag tag;
|
||||
+ public CompoundTag tag; // Paper private -> public
|
||||
private boolean emptyCacheFlag;
|
||||
private Entity entityRepresentation;
|
||||
private BlockInWorld cachedBreakBlock;
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java
|
||||
index eebaeaccc3ba1a9ec089d84b8de6c9d36034868f..6a1289424421083876d1808b7328cd3f01063a7e 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java
|
||||
@@ -25,6 +25,7 @@ import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
+import net.minecraft.nbt.ListTag;
|
||||
import net.minecraft.nbt.NbtUtils;
|
||||
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
@@ -152,9 +153,37 @@ public class SkullBlockEntity extends BlockEntity /*implements ITickable*/ { //
|
||||
@Nullable
|
||||
@Override
|
||||
public ClientboundBlockEntityDataPacket getUpdatePacket() {
|
||||
- return new ClientboundBlockEntityDataPacket(this.worldPosition, 4, this.getUpdateTag());
|
||||
+ return new ClientboundBlockEntityDataPacket(this.worldPosition, 4, sanitizeTileEntityUUID(this.getUpdateTag())); // Paper
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ public static CompoundTag sanitizeTileEntityUUID(CompoundTag cmp) {
|
||||
+ CompoundTag owner = cmp.getCompound("Owner");
|
||||
+ if (!owner.isEmpty()) {
|
||||
+ sanitizeUUID(owner);
|
||||
+ }
|
||||
+ return cmp;
|
||||
+ }
|
||||
+
|
||||
+ public static void sanitizeUUID(CompoundTag owner) {
|
||||
+ CompoundTag properties = owner.getCompound("Properties");
|
||||
+ ListTag list = null;
|
||||
+ if (!properties.isEmpty()) {
|
||||
+ list = properties.getList("textures", 10);
|
||||
+ }
|
||||
+
|
||||
+ if (list != null && !list.isEmpty()) {
|
||||
+ String textures = ((CompoundTag)list.get(0)).getString("Value");
|
||||
+ if (textures != null && textures.length() > 3) {
|
||||
+ UUID uuid = UUID.nameUUIDFromBytes(textures.getBytes());
|
||||
+ owner.setUUID("Id", uuid);
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+ owner.setUUID("Id", UUID.randomUUID());
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public CompoundTag getUpdateTag() {
|
||||
return this.save(new CompoundTag());
|
|
@ -1,184 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: miclebrick <miclebrick@outlook.com>
|
||||
Date: Wed, 8 Aug 2018 15:30:52 -0400
|
||||
Subject: [PATCH] Add Early Warning Feature to WatchDog
|
||||
|
||||
Detect when the server has been hung for a long duration, and start printing
|
||||
thread dumps at an interval until the point of crash.
|
||||
|
||||
This will help diagnose what was going on in that time before the crash.
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
||||
index bd508025b771424c942fd856c31d520b6f548082..62621562137cba4804f0465c58d25ca2786328e5 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
||||
@@ -25,6 +25,7 @@ import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import co.aikar.timings.Timings;
|
||||
import co.aikar.timings.TimingsManager;
|
||||
import org.spigotmc.SpigotConfig;
|
||||
+import org.spigotmc.WatchdogThread;
|
||||
|
||||
public class PaperConfig {
|
||||
|
||||
@@ -297,6 +298,14 @@ public class PaperConfig {
|
||||
}
|
||||
}
|
||||
|
||||
+ public static int watchdogPrintEarlyWarningEvery = 5000;
|
||||
+ public static int watchdogPrintEarlyWarningDelay = 10000;
|
||||
+ private static void watchdogEarlyWarning() {
|
||||
+ watchdogPrintEarlyWarningEvery = getInt("settings.watchdog.early-warning-every", 5000);
|
||||
+ watchdogPrintEarlyWarningDelay = getInt("settings.watchdog.early-warning-delay", 10000);
|
||||
+ WatchdogThread.doStart(SpigotConfig.timeoutTime, SpigotConfig.restartOnCrash );
|
||||
+ }
|
||||
+
|
||||
public static int tabSpamIncrement = 1;
|
||||
public static int tabSpamLimit = 500;
|
||||
private static void tabSpamLimiters() {
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index 125a75576442eaa4f1ff6dd153bdb31097497a3f..5a76ca77b974ff6fe862c9e05a88b507a34b44be 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -1017,6 +1017,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
this.updateStatusIcon(this.status);
|
||||
|
||||
// Spigot start
|
||||
+ org.spigotmc.WatchdogThread.hasStarted = true; // Paper
|
||||
Arrays.fill( recentTps, 20 );
|
||||
long start = System.nanoTime(), curTime, tickSection = start; // Paper - Further improve server tick loop
|
||||
lastTick = start - TICK_TIME; // Paper
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index 20915e40fbcf28faed603d449a99bf2157fcf972..5e36d705c56384f507fd85f704eae634379a27f1 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -808,6 +808,7 @@ public final class CraftServer implements Server {
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
+ org.spigotmc.WatchdogThread.hasStarted = false; // Paper - Disable watchdog early timeout on reload
|
||||
reloadCount++;
|
||||
configuration = YamlConfiguration.loadConfiguration(getConfigFile());
|
||||
commandsConfiguration = YamlConfiguration.loadConfiguration(getCommandsConfigFile());
|
||||
@@ -926,6 +927,7 @@ public final class CraftServer implements Server {
|
||||
enablePlugins(PluginLoadOrder.STARTUP);
|
||||
enablePlugins(PluginLoadOrder.POSTWORLD);
|
||||
getPluginManager().callEvent(new ServerLoadEvent(ServerLoadEvent.LoadType.RELOAD));
|
||||
+ org.spigotmc.WatchdogThread.hasStarted = true; // Paper - Disable watchdog early timeout on reload
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java
|
||||
index 652b820a4c0bbf7b6bbb8200927a663665583606..21ed80abe2134ecc769439705ab8bc46494df577 100644
|
||||
--- a/src/main/java/org/spigotmc/SpigotConfig.java
|
||||
+++ b/src/main/java/org/spigotmc/SpigotConfig.java
|
||||
@@ -229,7 +229,7 @@ public class SpigotConfig
|
||||
restartScript = getString( "settings.restart-script", restartScript );
|
||||
restartMessage = transform( getString( "messages.restart", "Server is restarting" ) );
|
||||
commands.put( "restart", new RestartCommand( "restart" ) );
|
||||
- WatchdogThread.doStart( timeoutTime, restartOnCrash );
|
||||
+ //WatchdogThread.doStart( timeoutTime, restartOnCrash ); // Paper - moved to PaperConfig
|
||||
}
|
||||
|
||||
public static boolean bungee;
|
||||
diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/spigotmc/WatchdogThread.java
|
||||
index ee0cca25ef458f2f0f7e450a2edea2b2adb7e846..16f6163bb53e73aa4ab6e22365342613b6b38118 100644
|
||||
--- a/src/main/java/org/spigotmc/WatchdogThread.java
|
||||
+++ b/src/main/java/org/spigotmc/WatchdogThread.java
|
||||
@@ -5,6 +5,7 @@ import java.lang.management.MonitorInfo;
|
||||
import java.lang.management.ThreadInfo;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
+import com.destroystokyo.paper.PaperConfig;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
@@ -14,6 +15,10 @@ public class WatchdogThread extends Thread
|
||||
private static WatchdogThread instance;
|
||||
private long timeoutTime;
|
||||
private boolean restart;
|
||||
+ private final long earlyWarningEvery; // Paper - Timeout time for just printing a dump but not restarting
|
||||
+ private final long earlyWarningDelay; // Paper
|
||||
+ public static volatile boolean hasStarted; // Paper
|
||||
+ private long lastEarlyWarning; // Paper - Keep track of short dump times to avoid spamming console with short dumps
|
||||
private volatile long lastTick;
|
||||
private volatile boolean stopping;
|
||||
|
||||
@@ -22,6 +27,8 @@ public class WatchdogThread extends Thread
|
||||
super( "Paper Watchdog Thread" );
|
||||
this.timeoutTime = timeoutTime;
|
||||
this.restart = restart;
|
||||
+ earlyWarningEvery = Math.min(PaperConfig.watchdogPrintEarlyWarningEvery, timeoutTime); // Paper
|
||||
+ earlyWarningDelay = Math.min(PaperConfig.watchdogPrintEarlyWarningDelay, timeoutTime); // Paper
|
||||
}
|
||||
|
||||
private static long monotonicMillis()
|
||||
@@ -60,10 +67,18 @@ public class WatchdogThread extends Thread
|
||||
{
|
||||
while ( !stopping )
|
||||
{
|
||||
- //
|
||||
- if ( lastTick != 0 && timeoutTime > 0 && monotonicMillis() > lastTick + timeoutTime && !Boolean.getBoolean("disable.watchdog")) // Paper - Add property to disable
|
||||
+ // Paper start
|
||||
+ Logger log = Bukkit.getServer().getLogger();
|
||||
+ long currentTime = monotonicMillis();
|
||||
+ if ( lastTick != 0 && timeoutTime > 0 && currentTime > lastTick + earlyWarningEvery && !Boolean.getBoolean("disable.watchdog") )
|
||||
{
|
||||
- Logger log = Bukkit.getServer().getLogger();
|
||||
+ boolean isLongTimeout = currentTime > lastTick + timeoutTime;
|
||||
+ // Don't spam early warning dumps
|
||||
+ if ( !isLongTimeout && (earlyWarningEvery <= 0 || !hasStarted || currentTime < lastEarlyWarning + earlyWarningEvery || currentTime < lastTick + earlyWarningDelay)) continue;
|
||||
+ if ( !isLongTimeout && MinecraftServer.getServer().hasStopped()) continue; // Don't spam early watchdog warnings during shutdown, we'll come back to this...
|
||||
+ lastEarlyWarning = currentTime;
|
||||
+ if (isLongTimeout) {
|
||||
+ // Paper end
|
||||
log.log( Level.SEVERE, "------------------------------" );
|
||||
log.log( Level.SEVERE, "The server has stopped responding! This is (probably) not a Paper bug." ); // Paper
|
||||
log.log( Level.SEVERE, "If you see a plugin in the Server thread dump below, then please report it to that author" );
|
||||
@@ -93,29 +108,46 @@ public class WatchdogThread extends Thread
|
||||
}
|
||||
}
|
||||
// Paper end
|
||||
+ } else
|
||||
+ {
|
||||
+ log.log(Level.SEVERE, "--- DO NOT REPORT THIS TO PAPER - THIS IS NOT A BUG OR A CRASH - " + Bukkit.getServer().getVersion() + " ---");
|
||||
+ log.log(Level.SEVERE, "The server has not responded for " + (currentTime - lastTick) / 1000 + " seconds! Creating thread dump");
|
||||
+ }
|
||||
+ // Paper end - Different message for short timeout
|
||||
log.log( Level.SEVERE, "------------------------------" );
|
||||
log.log( Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Paper!):" ); // Paper
|
||||
dumpThread( ManagementFactory.getThreadMXBean().getThreadInfo( MinecraftServer.getServer().serverThread.getId(), Integer.MAX_VALUE ), log );
|
||||
log.log( Level.SEVERE, "------------------------------" );
|
||||
//
|
||||
+ // Paper start - Only print full dump on long timeouts
|
||||
+ if ( isLongTimeout )
|
||||
+ {
|
||||
log.log( Level.SEVERE, "Entire Thread Dump:" );
|
||||
ThreadInfo[] threads = ManagementFactory.getThreadMXBean().dumpAllThreads( true, true );
|
||||
for ( ThreadInfo thread : threads )
|
||||
{
|
||||
dumpThread( thread, log );
|
||||
}
|
||||
+ } else {
|
||||
+ log.log(Level.SEVERE, "--- DO NOT REPORT THIS TO PAPER - THIS IS NOT A BUG OR A CRASH ---");
|
||||
+ }
|
||||
+
|
||||
+
|
||||
log.log( Level.SEVERE, "------------------------------" );
|
||||
|
||||
+ if ( isLongTimeout )
|
||||
+ {
|
||||
if ( restart && !MinecraftServer.getServer().hasStopped() )
|
||||
{
|
||||
RestartCommand.restart();
|
||||
}
|
||||
break;
|
||||
+ } // Paper end
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
- sleep( 10000 );
|
||||
+ sleep( 1000 ); // Paper - Reduce check time to every second instead of every ten seconds, more consistent and allows for short timeout
|
||||
} catch ( InterruptedException ex )
|
||||
{
|
||||
interrupt();
|
|
@ -1,33 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Fri, 10 Aug 2018 22:11:49 -0400
|
||||
Subject: [PATCH] Make EnderDragon implement Mob
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftComplexLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftComplexLivingEntity.java
|
||||
index bba2e3152ee7073b75ecce1a4792178db20344db..aea39a6cb778d2ef88f66b632aebd824aaef2ea6 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftComplexLivingEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftComplexLivingEntity.java
|
||||
@@ -1,17 +1,17 @@
|
||||
package org.bukkit.craftbukkit.entity;
|
||||
|
||||
-import net.minecraft.world.entity.LivingEntity;
|
||||
+import net.minecraft.world.entity.Mob;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.ComplexLivingEntity;
|
||||
|
||||
-public abstract class CraftComplexLivingEntity extends CraftLivingEntity implements ComplexLivingEntity {
|
||||
- public CraftComplexLivingEntity(CraftServer server, LivingEntity entity) {
|
||||
+public abstract class CraftComplexLivingEntity extends CraftMob implements ComplexLivingEntity { // Paper
|
||||
+ public CraftComplexLivingEntity(CraftServer server, Mob entity) { // Paper
|
||||
super(server, entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
- public LivingEntity getHandle() {
|
||||
- return (LivingEntity) entity;
|
||||
+ public Mob getHandle() { // Paper
|
||||
+ return (Mob) entity; // Paper
|
||||
}
|
||||
|
||||
@Override
|
|
@ -1,147 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: egg82 <phantom_zero@ymail.com>
|
||||
Date: Tue, 7 Aug 2018 01:24:23 -0600
|
||||
Subject: [PATCH] Use ConcurrentHashMap in JsonList
|
||||
|
||||
This is specifically aimed at fixing #471
|
||||
|
||||
Using a ConcurrentHashMap because thread safety
|
||||
The performance benefit of Map over ConcurrentMap is negligabe at best in this scenaio, as most operations will be get and not add or remove
|
||||
Even without considering the use-case the benefits are still negligable
|
||||
|
||||
Original ideas for the system included an expiration policy and/or handler
|
||||
The simpler solution was to use a computeIfPresent in the get method
|
||||
This will simultaneously have an O(1) lookup time and automatically expire any values
|
||||
Since the get method (nor other similar methods) don't seem to have a critical need to flush the map to disk at any of these points further processing is simply wasteful
|
||||
Meaning the original function expired values unrelated to the current value without actually having any explicit need to
|
||||
|
||||
The h method was heavily modified to be much more efficient in its processing
|
||||
Also instead of being called on every get, it's now called just before a save
|
||||
This will eliminate stale values being flushed to disk
|
||||
|
||||
Modified isEmpty to use the isEmpty() method instead of the slightly confusing size() < 1
|
||||
The point of this is readability, but does have a side-benefit of a small microptimization
|
||||
|
||||
Finally, added a couple obfhelpers for the modified code
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
index 0bb397407b55bd1c464ac603ec4c189045aabbb2..7c307a16ca3962db65be09a0ddd058a4ce81c7be 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
@@ -614,7 +614,7 @@ public abstract class PlayerList {
|
||||
} else if (!this.isWhitelisted(gameprofile, event)) { // Paper
|
||||
//chatmessage = new ChatMessage("multiplayer.disconnect.not_whitelisted"); // Paper
|
||||
//event.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, org.spigotmc.SpigotConfig.whitelistMessage); // Spigot // Paper - moved to isWhitelisted
|
||||
- } else if (getIpBans().isBanned(socketaddress) && !getIpBans().get(socketaddress).hasExpired()) {
|
||||
+ } else if (getIpBans().isBanned(socketaddress) && getIpBans().get(socketaddress) != null && !getIpBans().get(socketaddress).hasExpired()) { // Paper - fix NPE with temp ip bans
|
||||
IpBanListEntry ipbanentry = this.ipBans.get(socketaddress);
|
||||
|
||||
chatmessage = new TranslatableComponent("multiplayer.disconnect.banned_ip.reason", new Object[]{ipbanentry.getReason()});
|
||||
diff --git a/src/main/java/net/minecraft/server/players/StoredUserList.java b/src/main/java/net/minecraft/server/players/StoredUserList.java
|
||||
index 2cb235d695c244863a37454df22d5d94a291524d..e2982a8ac5448110378bc92247952332bdffe12c 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/StoredUserList.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/StoredUserList.java
|
||||
@@ -12,6 +12,8 @@ import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
+import java.lang.reflect.ParameterizedType; // Paper
|
||||
+import java.lang.reflect.Type; // Paper
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
@@ -28,7 +30,22 @@ public abstract class StoredUserList<K, V extends StoredUserEntry<K>> {
|
||||
protected static final Logger LOGGER = LogManager.getLogger();
|
||||
private static final Gson GSON = (new GsonBuilder()).setPrettyPrinting().create();
|
||||
private final File file;
|
||||
- private final Map<String, V> map = Maps.newHashMap();
|
||||
+ // Paper - replace HashMap is ConcurrentHashMap
|
||||
+ private final Map<String, V> map = Maps.newConcurrentMap(); private final Map<String, V> getBackingMap() { return this.map; } // Paper - OBFHELPER
|
||||
+ private boolean e = true;
|
||||
+ private static final ParameterizedType f = new ParameterizedType() {
|
||||
+ public Type[] getActualTypeArguments() {
|
||||
+ return new Type[]{StoredUserEntry.class};
|
||||
+ }
|
||||
+
|
||||
+ public Type getRawType() {
|
||||
+ return List.class;
|
||||
+ }
|
||||
+
|
||||
+ public Type getOwnerType() {
|
||||
+ return null;
|
||||
+ }
|
||||
+ };
|
||||
|
||||
public StoredUserList(File file) {
|
||||
this.file = file;
|
||||
@@ -51,8 +68,13 @@ public abstract class StoredUserList<K, V extends StoredUserEntry<K>> {
|
||||
|
||||
@Nullable
|
||||
public V get(K key) {
|
||||
- this.removeExpired();
|
||||
- return (V) this.map.get(this.getKeyForUser(key)); // CraftBukkit - fix decompile error
|
||||
+ // Paper start
|
||||
+ // this.g();
|
||||
+ // return (V) this.d.get(this.a(k0)); // CraftBukkit - fix decompile error
|
||||
+ return (V) this.getBackingMap().computeIfPresent(this.getMappingKey(key), (k, v) -> {
|
||||
+ return v.hasExpired() ? null : v;
|
||||
+ });
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
public void remove(K key) {
|
||||
@@ -81,9 +103,11 @@ public abstract class StoredUserList<K, V extends StoredUserEntry<K>> {
|
||||
// CraftBukkit end
|
||||
|
||||
public boolean isEmpty() {
|
||||
- return this.map.size() < 1;
|
||||
+ // return this.d.size() < 1; // Paper
|
||||
+ return this.getBackingMap().isEmpty(); // Paper - readability is the goal. As an aside, isEmpty() uses only sumCount() and a comparison. size() uses sumCount(), casts, and boolean logic
|
||||
}
|
||||
|
||||
+ protected final String getMappingKey(K k0) { return getKeyForUser(k0); } // Paper - OBFHELPER
|
||||
protected String getKeyForUser(K profile) {
|
||||
return profile.toString();
|
||||
}
|
||||
@@ -92,15 +116,16 @@ public abstract class StoredUserList<K, V extends StoredUserEntry<K>> {
|
||||
return this.map.containsKey(this.getKeyForUser(k0));
|
||||
}
|
||||
|
||||
+ private void removeStaleEntries() { removeExpired(); } // Paper - OBFHELPER
|
||||
private void removeExpired() {
|
||||
- List<K> list = Lists.newArrayList();
|
||||
- Iterator iterator = this.map.values().iterator();
|
||||
+ /*List<K> list = Lists.newArrayList();
|
||||
+ Iterator iterator = this.d.values().iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
V v0 = (V) iterator.next(); // CraftBukkit - decompile error
|
||||
|
||||
if (v0.hasExpired()) {
|
||||
- list.add(v0.getUser());
|
||||
+ list.add(v0.getKey());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,9 +134,11 @@ public abstract class StoredUserList<K, V extends StoredUserEntry<K>> {
|
||||
while (iterator.hasNext()) {
|
||||
K k0 = (K) iterator.next(); // CraftBukkit - decompile error
|
||||
|
||||
- this.map.remove(this.getKeyForUser(k0));
|
||||
- }
|
||||
+ this.d.remove(this.a(k0));
|
||||
+ }*/
|
||||
|
||||
+ this.getBackingMap().values().removeIf(StoredUserEntry::hasExpired);
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
protected abstract StoredUserEntry<K> createEntry(JsonObject json);
|
||||
@@ -121,6 +148,7 @@ public abstract class StoredUserList<K, V extends StoredUserEntry<K>> {
|
||||
}
|
||||
|
||||
public void save() throws IOException {
|
||||
+ this.removeStaleEntries(); // Paper - remove expired values before saving
|
||||
JsonArray jsonarray = new JsonArray();
|
||||
|
||||
this.map.values().stream().map((jsonlistentry) -> {
|
|
@ -1,39 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sun, 12 Aug 2018 02:33:39 -0400
|
||||
Subject: [PATCH] Use a Queue for Queueing Commands
|
||||
|
||||
Lists are bad as Queues mmmkay.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
index 9143fe99e43236bf65e6f098a30d522302ad78b7..4862a9519d4ba5f05b634a0335837bea9812edee 100644
|
||||
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
@@ -72,7 +72,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
|
||||
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
private static final Pattern SHA1 = Pattern.compile("^[a-fA-F0-9]{40}$");
|
||||
- private final List<ConsoleInput> consoleInput = Collections.synchronizedList(Lists.newArrayList());
|
||||
+ private final java.util.Queue<ConsoleInput> serverCommandQueue = new java.util.concurrent.ConcurrentLinkedQueue<>(); // Paper - use a proper queue
|
||||
private QueryThreadGs4 queryThreadGs4;
|
||||
public final RconConsoleSource rconConsoleSource;
|
||||
private RconThread rconThread;
|
||||
@@ -426,13 +426,15 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
|
||||
}
|
||||
|
||||
public void handleConsoleInput(String command, CommandSourceStack commandSource) {
|
||||
- this.consoleInput.add(new ConsoleInput(command, commandSource));
|
||||
+ this.serverCommandQueue.add(new ConsoleInput(command, commandSource));
|
||||
}
|
||||
|
||||
public void handleConsoleInputs() {
|
||||
MinecraftTimings.serverCommandTimer.startTiming(); // Spigot
|
||||
- while (!this.consoleInput.isEmpty()) {
|
||||
- ConsoleInput servercommand = (ConsoleInput) this.consoleInput.remove(0);
|
||||
+ // Paper start - use proper queue
|
||||
+ ConsoleInput servercommand;
|
||||
+ while ((servercommand = this.serverCommandQueue.poll()) != null) {
|
||||
+ // Paper end
|
||||
|
||||
// CraftBukkit start - ServerCommand for preprocessing
|
||||
ServerCommandEvent event = new ServerCommandEvent(console, servercommand.msg);
|
|
@ -1,73 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Wed, 15 Aug 2018 01:16:34 -0400
|
||||
Subject: [PATCH] Ability to get Tile Entities from a chunk without snapshots
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
|
||||
index 93b9e9d5932764f7e946dd3f8ab8191189c5d38f..423594177fe78600755d913f169f28dd1bfa2b37 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
|
||||
@@ -3,8 +3,10 @@ package org.bukkit.craftbukkit;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.base.Predicates;
|
||||
import java.lang.ref.WeakReference;
|
||||
+import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
+import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Registry;
|
||||
@@ -129,9 +131,16 @@ public class CraftChunk implements Chunk {
|
||||
|
||||
@Override
|
||||
public BlockState[] getTileEntities() {
|
||||
+ // Paper start
|
||||
+ return getTileEntities(true);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public BlockState[] getTileEntities(boolean useSnapshot) {
|
||||
if (!isLoaded()) {
|
||||
getWorld().getChunkAt(x, z); // Transient load for this tick
|
||||
}
|
||||
+ // Paper end
|
||||
int index = 0;
|
||||
net.minecraft.world.level.chunk.LevelChunk chunk = getHandle();
|
||||
|
||||
@@ -143,11 +152,33 @@ public class CraftChunk implements Chunk {
|
||||
}
|
||||
|
||||
BlockPos position = (BlockPos) obj;
|
||||
- entities[index++] = worldServer.getWorld().getBlockAt(position.getX(), position.getY(), position.getZ()).getState();
|
||||
+ entities[index++] = worldServer.getWorld().getBlockAt(position.getX(), position.getY(), position.getZ()).getState(useSnapshot); // Paper
|
||||
+ }
|
||||
+
|
||||
+ return entities;
|
||||
+ }
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public Collection<BlockState> getTileEntities(Predicate<Block> blockPredicate, boolean useSnapshot) {
|
||||
+ Preconditions.checkNotNull(blockPredicate, "blockPredicate");
|
||||
+ if (!isLoaded()) {
|
||||
+ getWorld().getChunkAt(x, z); // Transient load for this tick
|
||||
+ }
|
||||
+ net.minecraft.world.level.chunk.LevelChunk chunk = getHandle();
|
||||
+
|
||||
+ List<BlockState> entities = new ArrayList<>();
|
||||
+
|
||||
+ for (BlockPos position : chunk.blockEntities.keySet()) {
|
||||
+ Block block = worldServer.getWorld().getBlockAt(position.getX(), position.getY(), position.getZ());
|
||||
+ if (blockPredicate.test(block)) {
|
||||
+ entities.add(block.getState(useSnapshot));
|
||||
+ }
|
||||
}
|
||||
|
||||
return entities;
|
||||
}
|
||||
+ // Paper end
|
||||
|
||||
@Override
|
||||
public boolean isLoaded() {
|
|
@ -1,159 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: kashike <kashike@vq.lc>
|
||||
Date: Wed, 15 Aug 2018 01:26:09 -0700
|
||||
Subject: [PATCH] Allow disabling armour stand ticking
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
index 3562950df4868b1393790b1a1ff1fe0dc589c155..5ab0e7183e48134b7a0f736462516b1a8a333b04 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
@@ -384,4 +384,10 @@ public class PaperWorldConfig {
|
||||
private void armorStandEntityLookups() {
|
||||
armorStandEntityLookups = getBoolean("armor-stands-do-collision-entity-lookups", true);
|
||||
}
|
||||
+
|
||||
+ public boolean armorStandTick = true;
|
||||
+ private void armorStandTick() {
|
||||
+ this.armorStandTick = this.getBoolean("armor-stands-tick", this.armorStandTick);
|
||||
+ log("ArmorStand ticking is " + (this.armorStandTick ? "enabled" : "disabled") + " by default");
|
||||
+ }
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
index 06e52a0c5decf717e35c605d6bcb46c3c7b29656..2994eee1d381af2c9ff3649dd48a2ae14c38c9d7 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
@@ -77,9 +77,16 @@ public class ArmorStand extends LivingEntity {
|
||||
public Rotations leftLegPose;
|
||||
public Rotations rightLegPose;
|
||||
public boolean canMove = true; // Paper
|
||||
+ // Paper start - Allow ArmorStands not to tick
|
||||
+ public boolean canTick = true;
|
||||
+ public boolean canTickSetByAPI = false;
|
||||
+ private boolean noTickPoseDirty = false;
|
||||
+ private boolean noTickEquipmentDirty = false;
|
||||
+ // Paper end
|
||||
|
||||
public ArmorStand(EntityType<? extends ArmorStand> type, Level world) {
|
||||
super(type, world);
|
||||
+ if (world != null) this.canTick = world.paperConfig.armorStandTick; // Paper - armour stand ticking
|
||||
this.handItems = NonNullList.a(2, ItemStack.EMPTY);
|
||||
this.armorItems = NonNullList.a(4, ItemStack.EMPTY);
|
||||
this.headPose = ArmorStand.DEFAULT_HEAD_POSE;
|
||||
@@ -175,6 +182,7 @@ public class ArmorStand extends LivingEntity {
|
||||
this.armorItems.set(enumitemslot.getIndex(), itemstack);
|
||||
}
|
||||
|
||||
+ this.noTickEquipmentDirty = true; // Paper - Allow equipment to be updated even when tick disabled
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -255,6 +263,7 @@ public class ArmorStand extends LivingEntity {
|
||||
}
|
||||
|
||||
tag.put("Pose", this.writePose());
|
||||
+ if (this.canTickSetByAPI) tag.putBoolean("Paper.CanTickOverride", this.canTick); // Paper - persist no tick setting
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -286,6 +295,12 @@ public class ArmorStand extends LivingEntity {
|
||||
this.setNoBasePlate(tag.getBoolean("NoBasePlate"));
|
||||
this.setMarker(tag.getBoolean("Marker"));
|
||||
this.noPhysics = !this.hasPhysics();
|
||||
+ // Paper start - persist no tick
|
||||
+ if (tag.contains("Paper.CanTickOverride")) {
|
||||
+ this.canTick = tag.getBoolean("Paper.CanTickOverride");
|
||||
+ this.canTickSetByAPI = true;
|
||||
+ }
|
||||
+ // Paper end
|
||||
CompoundTag nbttagcompound1 = tag.getCompound("Pose");
|
||||
|
||||
this.readPose(nbttagcompound1);
|
||||
@@ -641,7 +656,29 @@ public class ArmorStand extends LivingEntity {
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
+ // Paper start
|
||||
+ if (!this.canTick) {
|
||||
+ if (this.noTickPoseDirty) {
|
||||
+ this.noTickPoseDirty = false;
|
||||
+ this.updatePose();
|
||||
+ }
|
||||
+
|
||||
+ if (this.noTickEquipmentDirty) {
|
||||
+ this.noTickEquipmentDirty = false;
|
||||
+ this.detectEquipmentUpdates();
|
||||
+ }
|
||||
+
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
super.tick();
|
||||
+ // Paper start - Split into separate method
|
||||
+ updatePose();
|
||||
+ }
|
||||
+
|
||||
+ public void updatePose() {
|
||||
+ // Paper end
|
||||
Rotations vector3f = (Rotations) this.entityData.get(ArmorStand.DATA_HEAD_POSE);
|
||||
|
||||
if (!this.headPose.equals(vector3f)) {
|
||||
@@ -764,29 +801,36 @@ public class ArmorStand extends LivingEntity {
|
||||
public void setHeadPose(Rotations vector3f) {
|
||||
this.headPose = vector3f;
|
||||
this.entityData.set(ArmorStand.DATA_HEAD_POSE, vector3f);
|
||||
+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking
|
||||
}
|
||||
|
||||
public void setBodyPose(Rotations vector3f) {
|
||||
this.bodyPose = vector3f;
|
||||
this.entityData.set(ArmorStand.DATA_BODY_POSE, vector3f);
|
||||
+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking
|
||||
}
|
||||
|
||||
public void setLeftArmPose(Rotations vector3f) {
|
||||
this.leftArmPose = vector3f;
|
||||
this.entityData.set(ArmorStand.DATA_LEFT_ARM_POSE, vector3f);
|
||||
+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking
|
||||
}
|
||||
|
||||
public void setRightArmPose(Rotations vector3f) {
|
||||
this.rightArmPose = vector3f;
|
||||
this.entityData.set(ArmorStand.DATA_RIGHT_ARM_POSE, vector3f);
|
||||
+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking
|
||||
}
|
||||
|
||||
public void setLeftLegPose(Rotations vector3f) {
|
||||
+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking
|
||||
this.leftLegPose = vector3f;
|
||||
this.entityData.set(ArmorStand.DATA_LEFT_LEG_POSE, vector3f);
|
||||
+
|
||||
}
|
||||
|
||||
public void setRightLegPose(Rotations vector3f) {
|
||||
+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking
|
||||
this.rightLegPose = vector3f;
|
||||
this.entityData.set(ArmorStand.DATA_RIGHT_LEG_POSE, vector3f);
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java
|
||||
index d4da5214a39b718671dcaf687cb0ff8668ce9728..8363b1b2267da30cda2fb8ea4e844598e20e1422 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java
|
||||
@@ -311,5 +311,16 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand {
|
||||
public boolean isSlotDisabled(org.bukkit.inventory.EquipmentSlot slot) {
|
||||
return getHandle().isSlotDisabled(org.bukkit.craftbukkit.CraftEquipmentSlot.getNMS(slot));
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean canTick() {
|
||||
+ return this.getHandle().canTick;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setCanTick(final boolean tick) {
|
||||
+ this.getHandle().canTick = tick;
|
||||
+ this.getHandle().canTickSetByAPI = true;
|
||||
+ }
|
||||
// Paper end
|
||||
}
|
|
@ -1,100 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
Date: Wed, 15 Aug 2018 12:05:12 -0700
|
||||
Subject: [PATCH] Optimize BlockPosition helper methods
|
||||
|
||||
Resolves #1338
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/core/BlockPos.java b/src/main/java/net/minecraft/core/BlockPos.java
|
||||
index c5089b0da33a68e7cadbc4841b07f9d772d224a0..b13e5d05d862ea8c6031b8071f525f00bc48f7e7 100644
|
||||
--- a/src/main/java/net/minecraft/core/BlockPos.java
|
||||
+++ b/src/main/java/net/minecraft/core/BlockPos.java
|
||||
@@ -121,58 +121,75 @@ public class BlockPos extends Vec3i {
|
||||
|
||||
@Override
|
||||
public BlockPos above() {
|
||||
- return this.relative(Direction.UP);
|
||||
+ return new BlockPos(this.getX(), this.getY() + 1, this.getZ()); // Paper - Optimize BlockPosition
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos above(int distance) {
|
||||
- return this.relative(Direction.UP, distance);
|
||||
+ return distance == 0 ? this : new BlockPos(this.getX(), this.getY() + distance, this.getZ()); // Paper - Optimize BlockPosition
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos below() {
|
||||
- return this.relative(Direction.DOWN);
|
||||
+ return new BlockPos(this.getX(), this.getY() - 1, this.getZ()); // Paper - Optimize BlockPosition
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos below(int distance) {
|
||||
- return this.relative(Direction.DOWN, distance);
|
||||
+ return distance == 0 ? this : new BlockPos(this.getX(), this.getY() - distance, this.getZ()); // Paper - Optimize BlockPosition
|
||||
}
|
||||
|
||||
public BlockPos north() {
|
||||
- return this.relative(Direction.NORTH);
|
||||
+ return new BlockPos(this.getX(), this.getY(), this.getZ() - 1); // Paper - Optimize BlockPosition
|
||||
}
|
||||
|
||||
public BlockPos north(int distance) {
|
||||
- return this.relative(Direction.NORTH, distance);
|
||||
+ return distance == 0 ? this : new BlockPos(this.getX(), this.getY(), this.getZ() - distance); // Paper - Optimize BlockPosition
|
||||
}
|
||||
|
||||
public BlockPos south() {
|
||||
- return this.relative(Direction.SOUTH);
|
||||
+ return new BlockPos(this.getX(), this.getY(), this.getZ() + 1); // Paper - Optimize BlockPosition
|
||||
}
|
||||
|
||||
public BlockPos south(int distance) {
|
||||
- return this.relative(Direction.SOUTH, distance);
|
||||
+ return distance == 0 ? this : new BlockPos(this.getX(), this.getY(), this.getZ() + distance); // Paper - Optimize BlockPosition
|
||||
}
|
||||
|
||||
public BlockPos west() {
|
||||
- return this.relative(Direction.WEST);
|
||||
+ return new BlockPos(this.getX() - 1, this.getY(), this.getZ()); // Paper - Optimize BlockPosition
|
||||
}
|
||||
|
||||
public BlockPos west(int distance) {
|
||||
- return this.relative(Direction.WEST, distance);
|
||||
+ return distance == 0 ? this : new BlockPos(this.getX() - distance, this.getY(), this.getZ()); // Paper - Optimize BlockPosition
|
||||
}
|
||||
|
||||
public BlockPos east() {
|
||||
- return this.relative(Direction.EAST);
|
||||
+ return new BlockPos(this.getX() + 1, this.getY(), this.getZ()); // Paper - Optimize BlockPosition
|
||||
}
|
||||
|
||||
public BlockPos east(int distance) {
|
||||
- return this.relative(Direction.EAST, distance);
|
||||
+ return distance == 0 ? this : new BlockPos(this.getX() + distance, this.getY(), this.getZ()); // Paper - Optimize BlockPosition
|
||||
}
|
||||
|
||||
public BlockPos relative(Direction direction) {
|
||||
- return new BlockPos(this.getX() + direction.getStepX(), this.getY() + direction.getStepY(), this.getZ() + direction.getStepZ());
|
||||
+ // Paper Start - Optimize BlockPosition
|
||||
+ switch(direction) {
|
||||
+ case UP:
|
||||
+ return new BlockPos(this.getX(), this.getY() + 1, this.getZ());
|
||||
+ case DOWN:
|
||||
+ return new BlockPos(this.getX(), this.getY() - 1, this.getZ());
|
||||
+ case NORTH:
|
||||
+ return new BlockPos(this.getX(), this.getY(), this.getZ() - 1);
|
||||
+ case SOUTH:
|
||||
+ return new BlockPos(this.getX(), this.getY(), this.getZ() + 1);
|
||||
+ case WEST:
|
||||
+ return new BlockPos(this.getX() - 1, this.getY(), this.getZ());
|
||||
+ case EAST:
|
||||
+ return new BlockPos(this.getX() + 1, this.getY(), this.getZ());
|
||||
+ default:
|
||||
+ return new BlockPos(this.getX() + direction.getStepX(), this.getY() + direction.getStepY(), this.getZ() + direction.getStepZ());
|
||||
+ }
|
||||
+ // Paper End
|
||||
}
|
||||
|
||||
@Override
|
|
@ -1,33 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sat, 18 Aug 2018 12:43:16 -0400
|
||||
Subject: [PATCH] Restore vanlla default mob-spawn-range and water animals
|
||||
limit
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java
|
||||
index 0efcbab8f8806aeb8dd8bd6384e5a7cee375d100..34ee684901906fc2ef5f0d09680d2686b813e52b 100644
|
||||
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
|
||||
+++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java
|
||||
@@ -165,7 +165,7 @@ public class SpigotWorldConfig
|
||||
public byte mobSpawnRange;
|
||||
private void mobSpawnRange()
|
||||
{
|
||||
- mobSpawnRange = (byte) getInt( "mob-spawn-range", 6 );
|
||||
+ mobSpawnRange = (byte) getInt( "mob-spawn-range", 8 ); // Paper - Vanilla
|
||||
log( "Mob Spawn Range: " + mobSpawnRange );
|
||||
}
|
||||
|
||||
diff --git a/src/main/resources/configurations/bukkit.yml b/src/main/resources/configurations/bukkit.yml
|
||||
index 6474a7fb738e1238cc272afc5ff14b645947e688..6d71bd0db752e6f523364ca5351579b6bcb434c8 100644
|
||||
--- a/src/main/resources/configurations/bukkit.yml
|
||||
+++ b/src/main/resources/configurations/bukkit.yml
|
||||
@@ -26,7 +26,7 @@ settings:
|
||||
spawn-limits:
|
||||
monsters: 70
|
||||
animals: 10
|
||||
- water-animals: 15
|
||||
+ water-animals: 5
|
||||
water-ambient: 20
|
||||
ambient: 15
|
||||
chunk-gc:
|
|
@ -1,229 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Fri, 24 Aug 2018 08:18:42 -0500
|
||||
Subject: [PATCH] Slime Pathfinder Events
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/Slime.java b/src/main/java/net/minecraft/world/entity/monster/Slime.java
|
||||
index fc8f26e988f1e4826dcfdcf071293bb356163e62..120ceb28ee3aee8a09cf67b45ac95d3d6613c133 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Slime.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Slime.java
|
||||
@@ -24,7 +24,6 @@ import net.minecraft.world.effect.MobEffects;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityDimensions;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
-import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.Mob;
|
||||
import net.minecraft.world.entity.MobSpawnType;
|
||||
import net.minecraft.world.entity.Pose;
|
||||
@@ -43,6 +42,13 @@ import net.minecraft.world.level.WorldGenLevel;
|
||||
import net.minecraft.world.level.biome.Biomes;
|
||||
import net.minecraft.world.level.levelgen.WorldgenRandom;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
+// Paper start
|
||||
+import com.destroystokyo.paper.event.entity.SlimeChangeDirectionEvent;
|
||||
+import com.destroystokyo.paper.event.entity.SlimeSwimEvent;
|
||||
+import com.destroystokyo.paper.event.entity.SlimeTargetLivingEntityEvent;
|
||||
+import com.destroystokyo.paper.event.entity.SlimeWanderEvent;
|
||||
+import org.bukkit.entity.LivingEntity;
|
||||
+// Paper end
|
||||
// CraftBukkit start
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -103,6 +109,7 @@ public class Slime extends Mob implements Enemy {
|
||||
@Override
|
||||
public void addAdditionalSaveData(CompoundTag tag) {
|
||||
super.addAdditionalSaveData(tag);
|
||||
+ tag.putBoolean("Paper.canWander", this.canWander); // Paper
|
||||
tag.putInt("Size", this.getSize() - 1);
|
||||
tag.putBoolean("wasOnGround", this.wasOnGround);
|
||||
}
|
||||
@@ -117,6 +124,11 @@ public class Slime extends Mob implements Enemy {
|
||||
|
||||
this.setSize(i + 1, false);
|
||||
super.readAdditionalSaveData(tag);
|
||||
+ // Paper start - check exists before loading or this will be loaded as false
|
||||
+ if (tag.contains("Paper.canWander")) {
|
||||
+ this.canWander = tag.getBoolean("Paper.canWander");
|
||||
+ }
|
||||
+ // Paper end
|
||||
this.wasOnGround = tag.getBoolean("wasOnGround");
|
||||
}
|
||||
|
||||
@@ -218,7 +230,7 @@ public class Slime extends Mob implements Enemy {
|
||||
super.remove();
|
||||
return;
|
||||
}
|
||||
- List<LivingEntity> slimes = new ArrayList<>(j);
|
||||
+ List<net.minecraft.world.entity.LivingEntity> slimes = new ArrayList<>(j);
|
||||
// CraftBukkit end
|
||||
|
||||
for (int l = 0; l < k; ++l) {
|
||||
@@ -242,7 +254,7 @@ public class Slime extends Mob implements Enemy {
|
||||
if (CraftEventFactory.callEntityTransformEvent(this, slimes, EntityTransformEvent.TransformReason.SPLIT).isCancelled()) {
|
||||
return;
|
||||
}
|
||||
- for (LivingEntity living : slimes) {
|
||||
+ for (net.minecraft.world.entity.LivingEntity living : slimes) {
|
||||
this.level.addEntity(living, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SLIME_SPLIT); // CraftBukkit - SpawnReason
|
||||
}
|
||||
// CraftBukkit end
|
||||
@@ -255,7 +267,7 @@ public class Slime extends Mob implements Enemy {
|
||||
public void push(Entity entity) {
|
||||
super.push(entity);
|
||||
if (entity instanceof IronGolem && this.isDealsDamage()) {
|
||||
- this.dealDamage((LivingEntity) entity);
|
||||
+ this.dealDamage((net.minecraft.world.entity.LivingEntity) entity);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -263,18 +275,18 @@ public class Slime extends Mob implements Enemy {
|
||||
@Override
|
||||
public void playerTouch(Player player) {
|
||||
if (this.isDealsDamage()) {
|
||||
- this.dealDamage((LivingEntity) player);
|
||||
+ this.dealDamage((net.minecraft.world.entity.LivingEntity) player);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
- protected void dealDamage(LivingEntity target) {
|
||||
+ protected void dealDamage(net.minecraft.world.entity.LivingEntity target) {
|
||||
if (this.isAlive()) {
|
||||
int i = this.getSize();
|
||||
|
||||
if (this.distanceToSqr((Entity) target) < 0.6D * (double) i * 0.6D * (double) i && this.canSee(target) && target.hurt(DamageSource.mobAttack(this), this.getAttackDamage())) {
|
||||
this.playSound(SoundEvents.SLIME_ATTACK, 1.0F, (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F);
|
||||
- this.doEnchantDamageEffects((LivingEntity) this, (Entity) target);
|
||||
+ this.doEnchantDamageEffects((net.minecraft.world.entity.LivingEntity) this, (Entity) target);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -396,7 +408,7 @@ public class Slime extends Mob implements Enemy {
|
||||
|
||||
@Override
|
||||
public boolean canUse() {
|
||||
- return !this.slime.isPassenger();
|
||||
+ return !this.slime.isPassenger() && this.slime.canWander && new SlimeWanderEvent((org.bukkit.entity.Slime) this.slime.getBukkitEntity()).callEvent(); // Paper
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -417,7 +429,7 @@ public class Slime extends Mob implements Enemy {
|
||||
|
||||
@Override
|
||||
public boolean canUse() {
|
||||
- return (this.slime.isInWater() || this.slime.isInLava()) && this.slime.getMoveControl() instanceof Slime.SlimeMoveControl;
|
||||
+ return (this.slime.isInWater() || this.slime.isInLava()) && this.slime.getMoveControl() instanceof Slime.SlimeMoveControl && this.slime.canWander && new SlimeSwimEvent((org.bukkit.entity.Slime) this.slime.getBukkitEntity()).callEvent(); // Paper
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -443,14 +455,18 @@ public class Slime extends Mob implements Enemy {
|
||||
|
||||
@Override
|
||||
public boolean canUse() {
|
||||
- return this.slime.getTarget() == null && (this.slime.onGround || this.slime.isInWater() || this.slime.isInLava() || this.slime.hasEffect(MobEffects.LEVITATION)) && this.slime.getMoveControl() instanceof Slime.SlimeMoveControl;
|
||||
+ return this.slime.getTarget() == null && (this.slime.onGround || this.slime.isInWater() || this.slime.isInLava() || this.slime.hasEffect(MobEffects.LEVITATION)) && this.slime.getMoveControl() instanceof Slime.SlimeMoveControl && this.slime.canWander; // Paper - add canWander
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
if (--this.nextRandomizeTime <= 0) {
|
||||
this.nextRandomizeTime = 40 + this.slime.getRandom().nextInt(60);
|
||||
- this.chosenDegrees = (float) this.slime.getRandom().nextInt(360);
|
||||
+ // Paper start
|
||||
+ SlimeChangeDirectionEvent event = new SlimeChangeDirectionEvent((org.bukkit.entity.Slime) this.slime.getBukkitEntity(), (float) this.slime.getRandom().nextInt(360));
|
||||
+ if (!this.slime.canWander || !event.callEvent()) return;
|
||||
+ this.chosenDegrees = event.getNewYaw();
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
((Slime.SlimeMoveControl) this.slime.getMoveControl()).setDirection(this.chosenDegrees, false);
|
||||
@@ -469,9 +485,17 @@ public class Slime extends Mob implements Enemy {
|
||||
|
||||
@Override
|
||||
public boolean canUse() {
|
||||
- LivingEntity entityliving = this.slime.getTarget();
|
||||
+ net.minecraft.world.entity.LivingEntity entityliving = this.slime.getTarget();
|
||||
|
||||
- return entityliving == null ? false : (!entityliving.isAlive() ? false : (entityliving instanceof Player && ((Player) entityliving).abilities.invulnerable ? false : this.slime.getMoveControl() instanceof Slime.SlimeMoveControl));
|
||||
+ // Paper start
|
||||
+ if (entityliving == null || !entityliving.isAlive()) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ if (entityliving instanceof Player && ((Player) entityliving).abilities.invulnerable) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ return this.slime.getMoveControl() instanceof Slime.SlimeMoveControl && this.slime.canWander && new SlimeTargetLivingEntityEvent((org.bukkit.entity.Slime) this.slime.getBukkitEntity(), (LivingEntity) entityliving.getBukkitEntity()).callEvent();
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -482,9 +506,17 @@ public class Slime extends Mob implements Enemy {
|
||||
|
||||
@Override
|
||||
public boolean canContinueToUse() {
|
||||
- LivingEntity entityliving = this.slime.getTarget();
|
||||
+ net.minecraft.world.entity.LivingEntity entityliving = this.slime.getTarget();
|
||||
|
||||
- return entityliving == null ? false : (!entityliving.isAlive() ? false : (entityliving instanceof Player && ((Player) entityliving).abilities.invulnerable ? false : --this.growTiredTimer > 0));
|
||||
+ // Paper start
|
||||
+ if (entityliving == null || !entityliving.isAlive()) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ if (entityliving instanceof Player && ((Player) entityliving).abilities.invulnerable) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ return --this.growTiredTimer > 0 && this.slime.canWander && new SlimeTargetLivingEntityEvent((org.bukkit.entity.Slime) this.slime.getBukkitEntity(), (LivingEntity) entityliving.getBukkitEntity()).callEvent();
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -492,6 +524,13 @@ public class Slime extends Mob implements Enemy {
|
||||
this.slime.lookAt((Entity) this.slime.getTarget(), 10.0F, 10.0F);
|
||||
((Slime.SlimeMoveControl) this.slime.getMoveControl()).setDirection(this.slime.yRot, this.slime.isDealsDamage());
|
||||
}
|
||||
+
|
||||
+ // Paper start - clear timer and target when goal resets
|
||||
+ public void stop() {
|
||||
+ this.growTiredTimer = 0;
|
||||
+ this.slime.setTarget(null);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
static class SlimeMoveControl extends MoveControl {
|
||||
@@ -550,4 +589,15 @@ public class Slime extends Mob implements Enemy {
|
||||
}
|
||||
}
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ private boolean canWander = true;
|
||||
+ public boolean canWander() {
|
||||
+ return canWander;
|
||||
+ }
|
||||
+
|
||||
+ public void setWander(boolean canWander) {
|
||||
+ this.canWander = canWander;
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftSlime.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftSlime.java
|
||||
index 93af0fd9e15954d7d9f28d7dc29ee18055908348..340036135588d06e43cbd229dd3a6613b04bb9ab 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftSlime.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftSlime.java
|
||||
@@ -34,4 +34,14 @@ public class CraftSlime extends CraftMob implements Slime {
|
||||
public EntityType getType() {
|
||||
return EntityType.SLIME;
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ public boolean canWander() {
|
||||
+ return getHandle().canWander();
|
||||
+ }
|
||||
+
|
||||
+ public void setWander(boolean canWander) {
|
||||
+ getHandle().setWander(canWander);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
|
@ -1,72 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Byteflux <byte@byteflux.net>
|
||||
Date: Wed, 8 Aug 2018 16:33:21 -0600
|
||||
Subject: [PATCH] Configurable speed for water flowing over lava
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
index 5ab0e7183e48134b7a0f736462516b1a8a333b04..f280dbff4a09bc611a9ca565c6d697d08801f53b 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
@@ -390,4 +390,10 @@ public class PaperWorldConfig {
|
||||
this.armorStandTick = this.getBoolean("armor-stands-tick", this.armorStandTick);
|
||||
log("ArmorStand ticking is " + (this.armorStandTick ? "enabled" : "disabled") + " by default");
|
||||
}
|
||||
+
|
||||
+ public int waterOverLavaFlowSpeed;
|
||||
+ private void waterOverLavaFlowSpeed() {
|
||||
+ waterOverLavaFlowSpeed = getInt("water-over-lava-flow-speed", 5);
|
||||
+ log("Water over lava flow speed: " + waterOverLavaFlowSpeed);
|
||||
+ }
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/LiquidBlock.java b/src/main/java/net/minecraft/world/level/block/LiquidBlock.java
|
||||
index f99b90e4b3210747077f2bf3adbcf7b5fb9821ec..97f2d9082e49010fb8780c5fdd8957f71b31e43e 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/LiquidBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/LiquidBlock.java
|
||||
@@ -23,6 +23,7 @@ import net.minecraft.world.level.material.FlowingFluid;
|
||||
import net.minecraft.world.level.material.Fluid;
|
||||
import net.minecraft.world.level.material.FluidState;
|
||||
import net.minecraft.world.level.material.Fluids;
|
||||
+import net.minecraft.world.level.material.Material;
|
||||
import net.minecraft.world.level.pathfinder.PathComputationType;
|
||||
import net.minecraft.world.level.storage.loot.LootContext;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
@@ -100,11 +101,28 @@ public class LiquidBlock extends Block implements BucketPickup {
|
||||
@Override
|
||||
public void onPlace(BlockState state, Level world, BlockPos pos, BlockState oldState, boolean notify) {
|
||||
if (this.shouldSpreadLiquid(world, pos, state)) {
|
||||
- world.getLiquidTicks().a(pos, state.getFluidState().getType(), this.fluid.getTickDelay((LevelReader) world));
|
||||
+ world.getLiquidTicks().a(pos, state.getFluidState().getType(), this.getFlowSpeed(world, pos)); // Paper
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+ // Paper start - Get flow speed. Throttle if its water and flowing adjacent to lava
|
||||
+ public int getFlowSpeed(Level world, BlockPos blockposition) {
|
||||
+ if (this.material == Material.WATER) {
|
||||
+ if (
|
||||
+ world.getMaterialIfLoaded(blockposition.north(1)) == Material.LAVA ||
|
||||
+ world.getMaterialIfLoaded(blockposition.south(1)) == Material.LAVA ||
|
||||
+ world.getMaterialIfLoaded(blockposition.west(1)) == Material.LAVA ||
|
||||
+ world.getMaterialIfLoaded(blockposition.east(1)) == Material.LAVA
|
||||
+ ) {
|
||||
+ return world.paperConfig.waterOverLavaFlowSpeed;
|
||||
+ }
|
||||
+ }
|
||||
+ return this.fluid.getTickDelay(world);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
+
|
||||
@Override
|
||||
public BlockState updateShape(BlockState state, Direction direction, BlockState newState, LevelAccessor world, BlockPos pos, BlockPos posFrom) {
|
||||
if (state.getFluidState().isSource() || newState.getFluidState().isSource()) {
|
||||
@@ -117,7 +135,7 @@ public class LiquidBlock extends Block implements BucketPickup {
|
||||
@Override
|
||||
public void neighborChanged(BlockState state, Level world, BlockPos pos, Block block, BlockPos fromPos, boolean notify) {
|
||||
if (this.shouldSpreadLiquid(world, pos, state)) {
|
||||
- world.getLiquidTicks().a(pos, state.getFluidState().getType(), this.fluid.getTickDelay((LevelReader) world));
|
||||
+ world.getLiquidTicks().a(pos, state.getFluidState().getType(), this.getFlowSpeed(world, pos)); // Paper
|
||||
}
|
||||
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: miclebrick <miclebrick@outlook.com>
|
||||
Date: Thu, 23 Aug 2018 11:45:32 -0400
|
||||
Subject: [PATCH] Optimize CraftBlockData Creation
|
||||
|
||||
Avoids a hashmap lookup by cacheing a reference to the CraftBlockData
|
||||
and cloning it when one is needed.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java
|
||||
index 5d7794c9533bd37193f196bda616adaaace2bbde..57eedaeedaa24bd274fb55c6e4521f1305382645 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java
|
||||
@@ -374,6 +374,14 @@ public abstract class BlockBehaviour {
|
||||
this.hasPostProcess = blockbase_info.hasPostProcess;
|
||||
this.emissiveRendering = blockbase_info.emissiveRendering;
|
||||
}
|
||||
+ // Paper start - impl cached craft block data, lazy load to fix issue with loading at the wrong time
|
||||
+ private org.bukkit.craftbukkit.block.data.CraftBlockData cachedCraftBlockData;
|
||||
+
|
||||
+ public org.bukkit.craftbukkit.block.data.CraftBlockData createCraftBlockData() {
|
||||
+ if (cachedCraftBlockData == null) cachedCraftBlockData = org.bukkit.craftbukkit.block.data.CraftBlockData.createData(getBlockData());
|
||||
+ return (org.bukkit.craftbukkit.block.data.CraftBlockData) cachedCraftBlockData.clone();
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
public void initCache() {
|
||||
if (!this.getBlock().hasDynamicShape()) {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java b/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java
|
||||
index 3a90b504ebbe86350f5fee5baa818e40d884d24f..0b6c6dfc380cea87bd88c3eb8a199e072dcbf56c 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java
|
||||
@@ -509,7 +509,17 @@ public class CraftBlockData implements BlockData {
|
||||
return craft;
|
||||
}
|
||||
|
||||
+ // Paper start - optimize creating BlockData to not need a map lookup
|
||||
+ static {
|
||||
+ // Initialize cached data for all IBlockData instances after registration
|
||||
+ Block.BLOCK_STATE_REGISTRY.iterator().forEachRemaining(BlockState::createCraftBlockData);
|
||||
+ }
|
||||
public static CraftBlockData fromData(BlockState data) {
|
||||
+ return data.createCraftBlockData();
|
||||
+ }
|
||||
+
|
||||
+ public static CraftBlockData createData(BlockState data) {
|
||||
+ // Paper end
|
||||
return MAP.getOrDefault(data.getBlock().getClass(), CraftBlockData::new).apply(data);
|
||||
}
|
||||
|
|
@ -1,96 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sun, 26 Aug 2018 20:49:50 -0400
|
||||
Subject: [PATCH] Optimize RegistryMaterials
|
||||
|
||||
Use larger initial sizes to increase bucket capacity on the BiMap
|
||||
|
||||
BiMap.get was seen to be using a good bit of CPU time.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/core/MappedRegistry.java b/src/main/java/net/minecraft/core/MappedRegistry.java
|
||||
index 928d4b980a1f703915454ffb304dc329fa4223df..da3733db4a5817673703f6c0cf37b5ee3bf91a99 100644
|
||||
--- a/src/main/java/net/minecraft/core/MappedRegistry.java
|
||||
+++ b/src/main/java/net/minecraft/core/MappedRegistry.java
|
||||
@@ -30,6 +30,7 @@ import net.minecraft.Util;
|
||||
import net.minecraft.resources.RegistryDataPackCodec;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
+import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap; // Paper
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
@@ -38,7 +39,7 @@ public class MappedRegistry<T> extends WritableRegistry<T> {
|
||||
|
||||
protected static final Logger LOGGER = LogManager.getLogger();
|
||||
private final ObjectList<T> byId = new ObjectArrayList(256);
|
||||
- private final Object2IntMap<T> toId = new Object2IntOpenCustomHashMap(Util.identityStrategy());
|
||||
+ private final Reference2IntOpenHashMap<T> bg = new Reference2IntOpenHashMap<T>(2048);// Paper - use bigger expected size to reduce collisions and direct intent for FastUtil to be identity map
|
||||
private final BiMap<ResourceLocation, T> storage;
|
||||
private final BiMap<ResourceKey<T>, T> keyStorage;
|
||||
private final Map<T, Lifecycle> lifecycles;
|
||||
@@ -48,10 +49,10 @@ public class MappedRegistry<T> extends WritableRegistry<T> {
|
||||
|
||||
public MappedRegistry(ResourceKey<? extends Registry<T>> key, Lifecycle lifecycle) {
|
||||
super(key, lifecycle);
|
||||
- this.toId.defaultReturnValue(-1);
|
||||
- this.storage = HashBiMap.create();
|
||||
- this.keyStorage = HashBiMap.create();
|
||||
- this.lifecycles = Maps.newIdentityHashMap();
|
||||
+ this.bg.defaultReturnValue(-1);
|
||||
+ this.storage = HashBiMap.create(2048); // Paper - use bigger expected size to reduce collisions
|
||||
+ this.keyStorage = HashBiMap.create(2048); // Paper - use bigger expected size to reduce collisions
|
||||
+ this.lifecycles = new java.util.IdentityHashMap<>(2048); // Paper - use bigger expected size to reduce collisions
|
||||
this.elementsLifecycle = lifecycle;
|
||||
}
|
||||
|
||||
@@ -77,7 +78,7 @@ public class MappedRegistry<T> extends WritableRegistry<T> {
|
||||
Validate.notNull(entry);
|
||||
this.byId.size(Math.max(this.byId.size(), rawId + 1));
|
||||
this.byId.set(rawId, entry);
|
||||
- this.toId.put(entry, rawId);
|
||||
+ this.bg.put(entry, rawId);
|
||||
this.randomCache = null;
|
||||
if (checkDuplicateKeys && this.keyStorage.containsKey(key)) {
|
||||
MappedRegistry.LOGGER.debug("Adding duplicate key '{}' to registry", key);
|
||||
@@ -113,12 +114,12 @@ public class MappedRegistry<T> extends WritableRegistry<T> {
|
||||
if (t0 == null) {
|
||||
i = rawId.isPresent() ? rawId.getAsInt() : this.nextId;
|
||||
} else {
|
||||
- i = this.toId.getInt(t0);
|
||||
+ i = this.bg.getInt(t0);
|
||||
if (rawId.isPresent() && rawId.getAsInt() != i) {
|
||||
throw new IllegalStateException("ID mismatch");
|
||||
}
|
||||
|
||||
- this.toId.removeInt(t0);
|
||||
+ this.bg.removeInt(t0);
|
||||
this.lifecycles.remove(t0);
|
||||
}
|
||||
|
||||
@@ -138,7 +139,7 @@ public class MappedRegistry<T> extends WritableRegistry<T> {
|
||||
|
||||
@Override
|
||||
public int getId(@Nullable T entry) {
|
||||
- return this.toId.getInt(entry);
|
||||
+ return this.bg.getInt(entry);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -195,7 +196,7 @@ public class MappedRegistry<T> extends WritableRegistry<T> {
|
||||
this.randomCache = collection.toArray(new Object[collection.size()]);
|
||||
}
|
||||
|
||||
- return Util.getRandom(this.randomCache, random);
|
||||
+ return (T) Util.getRandom(this.randomCache, random); // Paper - Decompile fix
|
||||
}
|
||||
|
||||
public static <T> Codec<MappedRegistry<T>> networkCodec(ResourceKey<? extends Registry<T>> resourcekey, Lifecycle lifecycle, Codec<T> entryCodec) {
|
||||
@@ -215,7 +216,7 @@ public class MappedRegistry<T> extends WritableRegistry<T> {
|
||||
Iterator iterator = registrymaterials.iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
- T t0 = iterator.next();
|
||||
+ T t0 = (T) iterator.next(); // Paper - Decompile fix
|
||||
|
||||
builder.add(new MappedRegistry.RegistryEntry<>((ResourceKey) registrymaterials.getResourceKey(t0).get(), registrymaterials.getId(t0), t0));
|
||||
}
|
|
@ -1,96 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Sat, 25 Aug 2018 19:56:51 -0500
|
||||
Subject: [PATCH] Add PhantomPreSpawnEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/Phantom.java b/src/main/java/net/minecraft/world/entity/monster/Phantom.java
|
||||
index 4a2fecdfbda34d6360d50e2ac017907a62b4a043..e37137a2890330b92e05d6f76c46ffc99a527803 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Phantom.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Phantom.java
|
||||
@@ -161,6 +161,11 @@ public class Phantom extends FlyingMob implements Enemy {
|
||||
}
|
||||
|
||||
this.setPhantomSize(tag.getInt("Size"));
|
||||
+ // Paper start
|
||||
+ if (tag.hasUUID("Paper.SpawningEntity")) {
|
||||
+ this.spawningEntity = tag.getUUID("Paper.SpawningEntity");
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -170,6 +175,11 @@ public class Phantom extends FlyingMob implements Enemy {
|
||||
tag.putInt("AY", this.anchorPoint.getY());
|
||||
tag.putInt("AZ", this.anchorPoint.getZ());
|
||||
tag.putInt("Size", this.getPhantomSize());
|
||||
+ // Paper start
|
||||
+ if (this.spawningEntity != null) {
|
||||
+ tag.setUUID("Paper.SpawningEntity", this.spawningEntity);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -216,6 +226,15 @@ public class Phantom extends FlyingMob implements Enemy {
|
||||
return entitysize.scale(f);
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ java.util.UUID spawningEntity;
|
||||
+
|
||||
+ public java.util.UUID getSpawningEntity() {
|
||||
+ return spawningEntity;
|
||||
+ }
|
||||
+ public void setSpawningEntity(java.util.UUID entity) { this.spawningEntity = entity; }
|
||||
+ // Paper end
|
||||
+
|
||||
class PhantomAttackPlayerTargetGoal extends Goal {
|
||||
|
||||
private final TargetingConditions attackTargeting;
|
||||
diff --git a/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java b/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java
|
||||
index ee18e2826f6390ef5a29557b733fd00db5bc409f..42effcbd3ca7c38a4e8b1aa835543ad243112a33 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java
|
||||
@@ -4,6 +4,7 @@ import java.util.Iterator;
|
||||
import java.util.Random;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
+import net.minecraft.server.MCUtil;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.stats.ServerStatsCounter;
|
||||
@@ -73,8 +74,17 @@ public class PhantomSpawner implements CustomSpawner {
|
||||
int k = 1 + random.nextInt(difficultydamagescaler.getDifficulty().getId() + 1);
|
||||
|
||||
for (int l = 0; l < k; ++l) {
|
||||
+ // Paper start
|
||||
+ com.destroystokyo.paper.event.entity.PhantomPreSpawnEvent event = new com.destroystokyo.paper.event.entity.PhantomPreSpawnEvent(MCUtil.toLocation(world, blockposition1), ((ServerPlayer) entityhuman).getBukkitEntity(), org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NATURAL);
|
||||
+ if (!event.callEvent()) {
|
||||
+ if (event.shouldAbortSpawn()) {
|
||||
+ break;
|
||||
+ }
|
||||
+ continue;
|
||||
+ }
|
||||
+ // Paper end
|
||||
Phantom entityphantom = (Phantom) EntityType.PHANTOM.create((Level) world);
|
||||
-
|
||||
+ entityphantom.setSpawningEntity(entityhuman.getUUID()); // Paper
|
||||
entityphantom.moveTo(blockposition1, 0.0F, 0.0F);
|
||||
groupdataentity = entityphantom.finalizeSpawn(world, difficultydamagescaler, MobSpawnType.NATURAL, groupdataentity, (CompoundTag) null);
|
||||
world.addAllEntities(entityphantom, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NATURAL); // CraftBukkit
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPhantom.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPhantom.java
|
||||
index 15eb09595dad996314c169f9dd7d381e43f77be9..92162fa22f5e98b7837bde5830bd47c31b8b52d8 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPhantom.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPhantom.java
|
||||
@@ -34,4 +34,10 @@ public class CraftPhantom extends CraftFlying implements Phantom {
|
||||
public EntityType getType() {
|
||||
return EntityType.PHANTOM;
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ public java.util.UUID getSpawningEntity() {
|
||||
+ return getHandle().getSpawningEntity();
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Fri, 24 Aug 2018 11:50:26 -0500
|
||||
Subject: [PATCH] Add More Creeper API
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/Creeper.java b/src/main/java/net/minecraft/world/entity/monster/Creeper.java
|
||||
index d9b5cf8ac01289801ded01d928fa7ead96551be5..336736fae0b49a05e48c1c70a225da316bb73e66 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Creeper.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Creeper.java
|
||||
@@ -289,7 +289,18 @@ public class Creeper extends Monster {
|
||||
}
|
||||
|
||||
public void ignite() {
|
||||
- this.entityData.set(Creeper.DATA_IS_IGNITED, true);
|
||||
+ // Paper start
|
||||
+ setIgnited(true);
|
||||
+ }
|
||||
+
|
||||
+ public void setIgnited(boolean ignited) {
|
||||
+ if (isIgnited() != ignited) {
|
||||
+ com.destroystokyo.paper.event.entity.CreeperIgniteEvent event = new com.destroystokyo.paper.event.entity.CreeperIgniteEvent((org.bukkit.entity.Creeper) getBukkitEntity(), ignited);
|
||||
+ if (event.callEvent()) {
|
||||
+ this.entityData.set(Creeper.DATA_IS_IGNITED, event.isIgnited());
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
public boolean canDropMobsSkull() {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftCreeper.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftCreeper.java
|
||||
index ded0b7c1619aada95492e7ec25c0e0f3d008d0ad..9f68beb8c79ed1c429ee9f9efab8b8604258293b 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftCreeper.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftCreeper.java
|
||||
@@ -100,4 +100,14 @@ public class CraftCreeper extends CraftMonster implements Creeper {
|
||||
public EntityType getType() {
|
||||
return EntityType.CREEPER;
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ public void setIgnited(boolean ignited) {
|
||||
+ getHandle().setIgnited(ignited);
|
||||
+ }
|
||||
+
|
||||
+ public boolean isIgnited() {
|
||||
+ return getHandle().isIgnited();
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <zach.brown@destroystokyo.com>
|
||||
Date: Tue, 28 Aug 2018 23:04:15 -0400
|
||||
Subject: [PATCH] Inventory#removeItemAnySlot
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java
|
||||
index 9d70ef8c3967596491a804e4d66f2ec1b13992c9..ef2d18d19a86b3701855aa1ac126462e663f8fcd 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java
|
||||
@@ -222,10 +222,16 @@ public class CraftInventory implements Inventory {
|
||||
}
|
||||
|
||||
private int first(ItemStack item, boolean withAmount) {
|
||||
+ // Paper start
|
||||
+ return first(item, withAmount, getStorageContents());
|
||||
+ }
|
||||
+
|
||||
+ private int first(ItemStack item, boolean withAmount, ItemStack[] inventory) {
|
||||
+ // Paper end
|
||||
if (item == null) {
|
||||
return -1;
|
||||
}
|
||||
- ItemStack[] inventory = getStorageContents();
|
||||
+ //ItemStack[] inventory = getStorageContents(); // Paper - let param deal
|
||||
for (int i = 0; i < inventory.length; i++) {
|
||||
if (inventory[i] == null) continue;
|
||||
|
||||
@@ -348,6 +354,17 @@ public class CraftInventory implements Inventory {
|
||||
|
||||
@Override
|
||||
public HashMap<Integer, ItemStack> removeItem(ItemStack... items) {
|
||||
+ // Paper start
|
||||
+ return removeItem(false, items);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public HashMap<Integer, ItemStack> removeItemAnySlot(ItemStack... items) {
|
||||
+ return removeItem(true, items);
|
||||
+ }
|
||||
+
|
||||
+ private HashMap<Integer, ItemStack> removeItem(boolean searchEntire, ItemStack... items) {
|
||||
+ // Paper end
|
||||
Validate.notNull(items, "Items cannot be null");
|
||||
HashMap<Integer, ItemStack> leftover = new HashMap<Integer, ItemStack>();
|
||||
|
||||
@@ -358,7 +375,10 @@ public class CraftInventory implements Inventory {
|
||||
int toDelete = item.getAmount();
|
||||
|
||||
while (true) {
|
||||
- int first = first(item, false);
|
||||
+ // Paper start - Allow searching entire contents
|
||||
+ ItemStack[] toSearch = searchEntire ? getContents() : getStorageContents();
|
||||
+ int first = first(item, false, toSearch);
|
||||
+ // Paper end
|
||||
|
||||
// Drat! we don't have this type in the inventory
|
||||
if (first == -1) {
|
|
@ -1,20 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
Date: Sun, 2 Sep 2018 19:34:33 -0700
|
||||
Subject: [PATCH] Make CraftWorld#loadChunk(int, int, false) load unconverted
|
||||
chunks
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
index 159c32d6678e83f2d98ea6a1ad48346c9de017e1..57a2af56b53567371fdb6d0a55866e1e4e37cf3b 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
@@ -490,7 +490,7 @@ public class CraftWorld implements World {
|
||||
@Override
|
||||
public boolean loadChunk(int x, int z, boolean generate) {
|
||||
org.spigotmc.AsyncCatcher.catchOp("chunk load"); // Spigot
|
||||
- ChunkAccess chunk = world.getChunkSource().getChunk(x, z, generate ? ChunkStatus.FULL : ChunkStatus.EMPTY, true);
|
||||
+ ChunkAccess chunk = world.getChunkSource().getChunk(x, z, generate || isChunkGenerated(x, z) ? ChunkStatus.FULL : ChunkStatus.EMPTY, true); // Paper
|
||||
|
||||
// If generate = false, but the chunk already exists, we will get this back.
|
||||
if (chunk instanceof ImposterProtoChunk) {
|
Loading…
Add table
Add a link
Reference in a new issue