diff --git a/Spigot-Server-Patches/Ability-to-get-Tile-Entities-from-a-chunk-without-sn.patch b/Spigot-Server-Patches/Ability-to-get-Tile-Entities-from-a-chunk-without-sn.patch index 9a9e5d6826..bd9cb8bc7b 100644 --- a/Spigot-Server-Patches/Ability-to-get-Tile-Entities-from-a-chunk-without-sn.patch +++ b/Spigot-Server-Patches/Ability-to-get-Tile-Entities-from-a-chunk-without-sn.patch @@ -5,7 +5,7 @@ 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 e657684995..9ba2fa5de0 100644 +index b4fcf25d4..fa078eb0e 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java @@ -0,0 +0,0 @@ public class CraftChunk implements Chunk { diff --git a/Spigot-Server-Patches/Add-Early-Warning-Feature-to-WatchDog.patch b/Spigot-Server-Patches/Add-Early-Warning-Feature-to-WatchDog.patch index ab5341f93f..49cf825ad7 100644 --- a/Spigot-Server-Patches/Add-Early-Warning-Feature-to-WatchDog.patch +++ b/Spigot-Server-Patches/Add-Early-Warning-Feature-to-WatchDog.patch @@ -9,7 +9,7 @@ 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 642e704ed6..2023b5af0f 100644 +index ef567579e..8062054ab 100644 --- a/src/main/java/com/destroystokyo/paper/PaperConfig.java +++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java @@ -0,0 +0,0 @@ import org.bukkit.configuration.file.YamlConfiguration; @@ -36,11 +36,11 @@ index 642e704ed6..2023b5af0f 100644 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 476a729ddf..4565a56b3f 100644 +index 359ce72fc..30952ade4 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -0,0 +0,0 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati - this.a(this.m); +@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant entitytypes, World world) { + super(entitytypes, world); @@ -0,0 +0,0 @@ public class EntityArmorStand extends EntityLiving { - this.leftLegPose = EntityArmorStand.bB; - this.rightLegPose = EntityArmorStand.bC; - this.noclip = this.isNoGravity(); + this.rightArmPose = EntityArmorStand.bx; + this.leftLegPose = EntityArmorStand.by; + this.rightLegPose = EntityArmorStand.bz; + if (world != null) this.canTick = world.paperConfig.armorStandTick; // Paper - armour stand ticking - this.setSize(0.5F, 1.975F); - this.Q = 0.0F; + this.K = 0.0F; } + @@ -0,0 +0,0 @@ public class EntityArmorStand extends EntityLiving { - this.bF.set(enumitemslot.b(), itemstack); + this.armorItems.set(enumitemslot.b(), itemstack); } + this.noTickEquipmentDirty = true; // Paper - Allow equipment to be updated even when tick disabled } - public boolean c(int i, ItemStack itemstack) { + @Override @@ -0,0 +0,0 @@ public class EntityArmorStand extends EntityLiving { } - nbttagcompound.set("Pose", this.z()); + nbttagcompound.set("Pose", this.B()); + nbttagcompound.setBoolean("Paper.CanTick", this.canTick); // Paper - persist no tick setting } - public void a(NBTTagCompound nbttagcompound) { + @Override @@ -0,0 +0,0 @@ public class EntityArmorStand extends EntityLiving { + this.setBasePlate(nbttagcompound.getBoolean("NoBasePlate")); this.setMarker(nbttagcompound.getBoolean("Marker")); - this.bI = !this.isMarker(); - this.noclip = this.isNoGravity(); + this.noclip = !this.A(); + // Paper start - persist no tick + if (nbttagcompound.hasKey("Paper.CanTick")) { + this.canTick = nbttagcompound.getBoolean("Paper.CanTick"); @@ -72,8 +72,8 @@ index c604182dd9..2c54e3e34a 100644 this.g(nbttagcompound1); @@ -0,0 +0,0 @@ public class EntityArmorStand extends EntityLiving { - } + @Override public void tick() { + // Paper start + if (!this.canTick) { @@ -92,56 +92,55 @@ index c604182dd9..2c54e3e34a 100644 + // Paper end + super.tick(); -+ + // Paper start - Split into separate method + updatePose(); + } + + public void updatePose() { + // Paper end - Vector3f vector3f = (Vector3f) this.datawatcher.get(EntityArmorStand.b); + Vector3f vector3f = (Vector3f) this.datawatcher.get(EntityArmorStand.c); if (!this.headPose.equals(vector3f)) { @@ -0,0 +0,0 @@ public class EntityArmorStand extends EntityLiving { public void setHeadPose(Vector3f vector3f) { this.headPose = vector3f; - this.datawatcher.set(EntityArmorStand.b, vector3f); + this.datawatcher.set(EntityArmorStand.c, vector3f); + this.noTickPoseDirty = true; // Paper - Allow updates when not ticking } public void setBodyPose(Vector3f vector3f) { this.bodyPose = vector3f; - this.datawatcher.set(EntityArmorStand.c, vector3f); + this.datawatcher.set(EntityArmorStand.d, vector3f); + this.noTickPoseDirty = true; // Paper - Allow updates when not ticking } public void setLeftArmPose(Vector3f vector3f) { this.leftArmPose = vector3f; - this.datawatcher.set(EntityArmorStand.d, vector3f); + this.datawatcher.set(EntityArmorStand.e, vector3f); + this.noTickPoseDirty = true; // Paper - Allow updates when not ticking } public void setRightArmPose(Vector3f vector3f) { this.rightArmPose = vector3f; - this.datawatcher.set(EntityArmorStand.e, vector3f); + this.datawatcher.set(EntityArmorStand.f, vector3f); + this.noTickPoseDirty = true; // Paper - Allow updates when not ticking } public void setLeftLegPose(Vector3f vector3f) { this.leftLegPose = vector3f; - this.datawatcher.set(EntityArmorStand.f, vector3f); + this.datawatcher.set(EntityArmorStand.g, vector3f); + this.noTickPoseDirty = true; // Paper - Allow updates when not ticking } public void setRightLegPose(Vector3f vector3f) { this.rightLegPose = vector3f; - this.datawatcher.set(EntityArmorStand.g, vector3f); + this.datawatcher.set(EntityArmorStand.bs, vector3f); + this.noTickPoseDirty = true; // Paper - Allow updates when not ticking } public Vector3f r() { diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java -index bc1ab273bd..cb32d64bd0 100644 +index 58bfe8c1c..2ed2960c5 100644 --- a/src/main/java/net/minecraft/server/EntityLiving.java +++ b/src/main/java/net/minecraft/server/EntityLiving.java @@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity { @@ -157,10 +156,10 @@ index bc1ab273bd..cb32d64bd0 100644 - - switch (enumitemslot.a()) { - case HAND: -- itemstack = (ItemStack) this.bB.get(enumitemslot.b()); +- itemstack = (ItemStack) this.bw.get(enumitemslot.b()); - break; - case ARMOR: -- itemstack = (ItemStack) this.bC.get(enumitemslot.b()); +- itemstack = (ItemStack) this.bx.get(enumitemslot.b()); - break; - default: - continue; @@ -176,7 +175,7 @@ index bc1ab273bd..cb32d64bd0 100644 - new PlayerArmorChangeEvent((Player) this.getBukkitEntity(), PlayerArmorChangeEvent.SlotType.valueOf(enumitemslot.name()), oldItem, newItem).callEvent(); - } - // Paper end -- ((WorldServer) this.world).getTracker().a((Entity) this, (Packet) (new PacketPlayOutEntityEquipment(this.getId(), enumitemslot, itemstack1))); +- ((WorldServer) this.world).getChunkProvider().broadcast(this, new PacketPlayOutEntityEquipment(this.getId(), enumitemslot, itemstack1)); - if (!itemstack.isEmpty()) { - this.getAttributeMap().a(itemstack.a(enumitemslot)); - } @@ -187,10 +186,10 @@ index bc1ab273bd..cb32d64bd0 100644 - - switch (enumitemslot.a()) { - case HAND: -- this.bB.set(enumitemslot.b(), itemstack1.isEmpty() ? ItemStack.a : itemstack1.cloneItemStack()); +- this.bw.set(enumitemslot.b(), itemstack1.isEmpty() ? ItemStack.a : itemstack1.cloneItemStack()); - break; - case ARMOR: -- this.bC.set(enumitemslot.b(), itemstack1.isEmpty() ? ItemStack.a : itemstack1.cloneItemStack()); +- this.bx.set(enumitemslot.b(), itemstack1.isEmpty() ? ItemStack.a : itemstack1.cloneItemStack()); - } - } - } @@ -213,10 +212,10 @@ index bc1ab273bd..cb32d64bd0 100644 + + switch (enumitemslot.a()) { + case HAND: -+ itemstack = (ItemStack) this.bB.get(enumitemslot.b()); ++ itemstack = (ItemStack) this.bw.get(enumitemslot.b()); + break; + case ARMOR: -+ itemstack = (ItemStack) this.bC.get(enumitemslot.b()); ++ itemstack = (ItemStack) this.bx.get(enumitemslot.b()); + break; + default: + continue; @@ -232,7 +231,7 @@ index bc1ab273bd..cb32d64bd0 100644 + new PlayerArmorChangeEvent((Player) this.getBukkitEntity(), PlayerArmorChangeEvent.SlotType.valueOf(enumitemslot.name()), oldItem, newItem).callEvent(); + } + // Paper end -+ ((WorldServer) this.world).getTracker().a((Entity) this, (Packet) (new PacketPlayOutEntityEquipment(this.getId(), enumitemslot, itemstack1))); ++ ((WorldServer) this.world).getChunkProvider().broadcast(this, new PacketPlayOutEntityEquipment(this.getId(), enumitemslot, itemstack1)); + if (!itemstack.isEmpty()) { + this.getAttributeMap().a(itemstack.a(enumitemslot)); + } @@ -243,10 +242,10 @@ index bc1ab273bd..cb32d64bd0 100644 + + switch (enumitemslot.a()) { + case HAND: -+ this.bB.set(enumitemslot.b(), itemstack1.isEmpty() ? ItemStack.a : itemstack1.cloneItemStack()); ++ this.bw.set(enumitemslot.b(), itemstack1.isEmpty() ? ItemStack.a : itemstack1.cloneItemStack()); + break; + case ARMOR: -+ this.bC.set(enumitemslot.b(), itemstack1.isEmpty() ? ItemStack.a : itemstack1.cloneItemStack()); ++ this.bx.set(enumitemslot.b(), itemstack1.isEmpty() ? ItemStack.a : itemstack1.cloneItemStack()); + } + } + } @@ -254,10 +253,10 @@ index bc1ab273bd..cb32d64bd0 100644 + // Paper end + protected float e(float f, float f1) { - float f2 = MathHelper.g(f - this.aQ); + float f2 = MathHelper.g(f - this.aK); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java -index 9f5c3b92e3..07ce93f17c 100644 +index 9f5c3b92e..07ce93f17 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java @@ -0,0 +0,0 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand { diff --git a/Spigot-Server-Patches/AnvilDamageEvent.patch b/Spigot-Server-Patches/AnvilDamageEvent.patch index 1f9e90e301..7afac2ec34 100644 --- a/Spigot-Server-Patches/AnvilDamageEvent.patch +++ b/Spigot-Server-Patches/AnvilDamageEvent.patch @@ -5,12 +5,12 @@ Subject: [PATCH] AnvilDamageEvent diff --git a/src/main/java/net/minecraft/server/ContainerAnvil.java b/src/main/java/net/minecraft/server/ContainerAnvil.java -index 1560dd382a..d206e04657 100644 +index ada5cf982..64a992152 100644 --- a/src/main/java/net/minecraft/server/ContainerAnvil.java +++ b/src/main/java/net/minecraft/server/ContainerAnvil.java @@ -0,0 +0,0 @@ public class ContainerAnvil extends Container { - if (!world.isClientSide) { - if (!entityhuman1.abilities.canInstantlyBuild && iblockdata.a(TagsBlock.ANVIL) && entityhuman1.getRandom().nextFloat() < 0.12F) { + + if (!entityhuman.abilities.canInstantlyBuild && iblockdata.a(TagsBlock.ANVIL) && entityhuman.getRandom().nextFloat() < 0.12F) { IBlockData iblockdata1 = BlockAnvil.a_(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); @@ -24,5 +24,5 @@ index 1560dd382a..d206e04657 100644 + // Paper end if (iblockdata1 == null) { - world.setAir(blockposition); + world.a(blockposition, false); -- \ No newline at end of file diff --git a/Spigot-Server-Patches/Break-up-and-make-tab-spam-limits-configurable.patch b/Spigot-Server-Patches/Break-up-and-make-tab-spam-limits-configurable.patch index 88d9b4901d..209e571644 100644 --- a/Spigot-Server-Patches/Break-up-and-make-tab-spam-limits-configurable.patch +++ b/Spigot-Server-Patches/Break-up-and-make-tab-spam-limits-configurable.patch @@ -22,7 +22,7 @@ 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 63fdd94818..642e704ed6 100644 +index 52adc671e..ef567579e 100644 --- a/src/main/java/com/destroystokyo/paper/PaperConfig.java +++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java @@ -0,0 +0,0 @@ public class PaperConfig { @@ -45,26 +45,26 @@ index 63fdd94818..642e704ed6 100644 + } } diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java -index 6d04c5733c..9a96078004 100644 +index a0f6addef..e59037211 100644 --- a/src/main/java/net/minecraft/server/PlayerConnection.java +++ b/src/main/java/net/minecraft/server/PlayerConnection.java -@@ -0,0 +0,0 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { +@@ -0,0 +0,0 @@ public class PlayerConnection implements PacketListenerPlayIn { // CraftBukkit start - multithreaded fields private volatile int chatThrottle; private static final AtomicIntegerFieldUpdater chatSpamField = AtomicIntegerFieldUpdater.newUpdater(PlayerConnection.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 j; - private final IntHashMap k = new IntHashMap<>(); -@@ -0,0 +0,0 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { - this.minecraftServer.methodProfiler.exit(); + private final Int2ShortMap k = new Int2ShortOpenHashMap(); +@@ -0,0 +0,0 @@ public class PlayerConnection implements PacketListenerPlayIn { + this.minecraftServer.getMethodProfiler().exit(); // CraftBukkit start for (int spam; (spam = this.chatThrottle) > 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; -@@ -0,0 +0,0 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { +@@ -0,0 +0,0 @@ public class PlayerConnection implements PacketListenerPlayIn { public void a(PacketPlayInTabComplete packetplayintabcomplete) { // PlayerConnectionUtils.ensureMainThread(packetplayintabcomplete, this, this.player.getWorldServer()); // Paper - run this async // CraftBukkit start diff --git a/Spigot-Server-Patches/Cache-World-Entity-Type-counts.patch b/Spigot-Server-Patches/Cache-World-Entity-Type-counts.patch deleted file mode 100644 index b0c7ba844d..0000000000 --- a/Spigot-Server-Patches/Cache-World-Entity-Type-counts.patch +++ /dev/null @@ -1,227 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Colin Godsey -Date: Wed, 8 Aug 2018 10:10:06 -0600 -Subject: [PATCH] Cache World Entity Type counts - -Optimizes mob spawning by keeping a count of entities by type - -diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldEntityList.java b/src/main/java/com/destroystokyo/paper/PaperWorldEntityList.java -new file mode 100644 -index 0000000000..a10a5bc138 ---- /dev/null -+++ b/src/main/java/com/destroystokyo/paper/PaperWorldEntityList.java -@@ -0,0 +0,0 @@ -+package com.destroystokyo.paper; -+ -+import net.minecraft.server.Entity; -+import net.minecraft.server.EntityInsentient; -+import net.minecraft.server.EnumCreatureType; -+import net.minecraft.server.IAnimal; -+import net.minecraft.server.MinecraftServer; -+import net.minecraft.server.World; -+import net.minecraft.server.WorldServer; -+ -+import java.util.ArrayList; -+import java.util.Collection; -+ -+public class PaperWorldEntityList extends ArrayList { -+ -+ private final WorldServer world; -+ private final int[] entityCounts = new int[EnumCreatureType.values().length]; -+ -+ -+ public PaperWorldEntityList(World world) { -+ this.world = (WorldServer) world; -+ } -+ -+ @Override -+ public boolean addAll(Collection c) { -+ for (Entity e : c) { -+ updateEntityCount(e, 1); -+ } -+ -+ return super.addAll(c); -+ } -+ -+ @Override -+ public boolean removeAll(Collection c) { -+ for (Object e : c) { -+ if (e instanceof Entity && ((Entity) e).getWorld() == world) { -+ updateEntityCount((Entity) e, -1); -+ } -+ } -+ -+ return super.removeAll(c); -+ } -+ -+ @Override -+ public boolean add(Entity e) { -+ updateEntityCount(e, 1); -+ -+ return super.add(e); -+ } -+ -+ @Override -+ public Entity remove(int index) { -+ guard(); -+ Entity entity = super.remove(index); -+ if (entity != null) updateEntityCount(entity, -1); -+ return entity; -+ } -+ -+ @Override -+ public boolean remove(Object o) { -+ guard(); -+ if (super.remove(o)) { -+ updateEntityCount((Entity) o, -1); -+ return true; -+ } -+ return false; -+ } -+ -+ private void guard() { -+ if (world.guardEntityList) { -+ throw new java.util.ConcurrentModificationException(); -+ } -+ } -+ -+ public int getCreatureCount(EnumCreatureType type) { -+ return entityCounts[type.ordinal()]; -+ } -+ -+ private void updateEntityCount(EnumCreatureType type, int amt) { -+ int count = entityCounts[type.ordinal()]; -+ -+ count += amt; -+ -+ if (count < 0) { -+ MinecraftServer.LOGGER.error("Paper - Entity count cache has gone negative"); -+ count = 0; -+ } -+ -+ entityCounts[type.ordinal()] = count; -+ } -+ -+ public void updateEntityCount(Entity entity, int amt) { -+ if (!(entity instanceof IAnimal)) return; -+ -+ if (entity instanceof EntityInsentient) { -+ EntityInsentient entityinsentient = (EntityInsentient) entity; -+ if (amt > 0 && entityinsentient.isTypeNotPersistent() && entityinsentient.isPersistent()) { -+ return; -+ } -+ } -+ if (amt < 0) { -+ if (!entity.hasBeenCounted) { -+ return; -+ } -+ // Only remove once, we remove from if the entity list is guarded, but may be called later -+ entity.hasBeenCounted = false; -+ } else { -+ if (entity.hasBeenCounted) { -+ return; -+ } -+ entity.hasBeenCounted = true; -+ } -+ -+ for (EnumCreatureType type : EnumCreatureType.values()) { -+ if (type.matches(entity)) { -+ updateEntityCount(type, amt); -+ break; -+ } -+ } -+ } -+} -diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java -index 4dc7c8ba68..90e0d9d453 100644 ---- a/src/main/java/net/minecraft/server/Entity.java -+++ b/src/main/java/net/minecraft/server/Entity.java -@@ -0,0 +0,0 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke - private boolean az; - public boolean dead; - public boolean shouldBeRemoved; // Paper -+ public boolean hasBeenCounted = false; // Paper - public float width; - public float length; - public float J; -diff --git a/src/main/java/net/minecraft/server/EntityInsentient.java b/src/main/java/net/minecraft/server/EntityInsentient.java -index ee5078370c..856ddf2a74 100644 ---- a/src/main/java/net/minecraft/server/EntityInsentient.java -+++ b/src/main/java/net/minecraft/server/EntityInsentient.java -@@ -0,0 +0,0 @@ public abstract class EntityInsentient extends EntityLiving { - - public void tick() { - super.tick(); -+ if (isTypeNotPersistent() && hasBeenCounted == this.isPersistent()) ((com.destroystokyo.paper.PaperWorldEntityList) this.world.entityList).updateEntityCount(this, hasBeenCounted ? -1 : 1); // Paper - adjust count if persistence state changes - if (!this.world.isClientSide) { - this.dl(); - if (this.ticksLived % 5 == 0) { -diff --git a/src/main/java/net/minecraft/server/EnumCreatureType.java b/src/main/java/net/minecraft/server/EnumCreatureType.java -index 79e52f7bac..42f6a6a93a 100644 ---- a/src/main/java/net/minecraft/server/EnumCreatureType.java -+++ b/src/main/java/net/minecraft/server/EnumCreatureType.java -@@ -0,0 +0,0 @@ public enum EnumCreatureType { - this.h = flag1; - } - -+ public boolean matches(Entity entity) { return innerClass().isAssignableFrom(entity.getClass()); } // Paper -+ public Class innerClass() { return this.a(); } // Paper - OBFHELPER - public Class a() { - return this.e; - } -diff --git a/src/main/java/net/minecraft/server/SpawnerCreature.java b/src/main/java/net/minecraft/server/SpawnerCreature.java -index e626165520..d125fae03b 100644 ---- a/src/main/java/net/minecraft/server/SpawnerCreature.java -+++ b/src/main/java/net/minecraft/server/SpawnerCreature.java -@@ -0,0 +0,0 @@ public final class SpawnerCreature { - - if ((!enumcreaturetype.c() || flag1) && (enumcreaturetype.c() || flag) && (!enumcreaturetype.d() || flag2)) { - k = limit * i / SpawnerCreature.b; // CraftBukkit - use per-world limits -- int l1 = worldserver.a(enumcreaturetype.a(), k); -+ int l1 = ((com.destroystokyo.paper.PaperWorldEntityList) worldserver.entityList).getCreatureCount(enumcreaturetype); // Paper - entity count cache - - if (l1 <= k) { - BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); -diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index e31e366249..b007eb36c7 100644 ---- a/src/main/java/net/minecraft/server/World.java -+++ b/src/main/java/net/minecraft/server/World.java -@@ -0,0 +0,0 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc - private static final EnumDirection[] a = EnumDirection.values(); - private int b = 63; - // Spigot start - guard entity list from removals -- public final List entityList = new java.util.ArrayList() -+ public final List entityList = new com.destroystokyo.paper.PaperWorldEntityList(this); -+ /* // Paper start - { - @Override - public Entity remove(int index) -@@ -0,0 +0,0 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc - } - } - }; -+ */ // Paper end - // Spigot end - protected final Set g = com.google.common.collect.Sets.newHashSet(); public Set getEntityUnloadQueue() { return g; };// Paper - OBFHELPER - //public final List tileEntityList = Lists.newArrayList(); // Paper - remove unused list -@@ -0,0 +0,0 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc - public final com.destroystokyo.paper.PaperWorldConfig paperConfig; // Paper - - public final co.aikar.timings.WorldTimingsHandler timings; // Paper -- private boolean guardEntityList; // Spigot -+ public boolean guardEntityList; // Spigot // Paper - public - public static BlockPosition lastPhysicsProblem; // Spigot -+ public static boolean haveWeSilencedAPhysicsCrash; -+ public static String blockLocation; - private org.spigotmc.TickLimiter entityLimiter; - private org.spigotmc.TickLimiter tileLimiter; - private int tileTickPosition; -@@ -0,0 +0,0 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc - Chunk chunk = entity.getCurrentChunk(); // Paper - if (chunk != null) chunk.removeEntity(entity); // Paper - entity.shouldBeRemoved = true; // Paper -+ ((com.destroystokyo.paper.PaperWorldEntityList) entityList).updateEntityCount(entity, -1); // Paper - - if (!guardEntityList) { // Spigot - It will get removed after the tick if we are ticking // Paper - always remove from current chunk above - // CraftBukkit start - Decrement loop variable field if we've already ticked this entity --- \ No newline at end of file diff --git a/Spigot-Server-Patches/Detect-and-repair-corrupt-Region-Files.patch b/Spigot-Server-Patches/Detect-and-repair-corrupt-Region-Files.patch index 7f57fb4069..c727015ec4 100644 --- a/Spigot-Server-Patches/Detect-and-repair-corrupt-Region-Files.patch +++ b/Spigot-Server-Patches/Detect-and-repair-corrupt-Region-Files.patch @@ -11,76 +11,53 @@ I don't know why mojang only checks for 4096, when anything less than 8192 is a But to be safe, it will attempt to back up the file. diff --git a/src/main/java/net/minecraft/server/RegionFile.java b/src/main/java/net/minecraft/server/RegionFile.java -index e2d4450e90..c20511588d 100644 +index 4e6288e8b..e68f90194 100644 --- a/src/main/java/net/minecraft/server/RegionFile.java +++ b/src/main/java/net/minecraft/server/RegionFile.java -@@ -0,0 +0,0 @@ public class RegionFile { - private static final boolean ENABLE_EXTENDED_SAVE = Boolean.parseBoolean(System.getProperty("net.minecraft.server.RegionFile.enableExtendedSave", "true")); +@@ -0,0 +0,0 @@ public class RegionFile implements AutoCloseable { // Spigot end private static final byte[] a = new byte[4096]; -- private final File b; -- private RandomAccessFile c; + private final RandomAccessFile b; private RandomAccessFile getDataFile() { return this.b; } // Paper - OBFHELPER +- private final int[] c = new int[1024]; - private final int[] d = new int[1024]; -- private final int[] e = new int[1024]; -+ private final File b;private File getFile() { return b; } // Paper - OBFHELPER -+ private RandomAccessFile c;private RandomAccessFile getDataFile() { return c; } // Paper - OBFHELPER -+ private final int[] d = new int[1024];private int[] offsets = d; // Paper - OBFHELPER -+ private final int[] e = new int[1024];private int[] timestamps = e; // Paper - OBFHELPER - private List f; - private int g; - private long h; -@@ -0,0 +0,0 @@ public class RegionFile { - } ++ private final int[] c = new int[1024]; private int[] offsets = c; // Paper - OBFHELPER ++ private final int[] d = new int[1024];private int[] timestamps = d; // Paper - OBFHELPER + private final List e; - this.c = new RandomAccessFile(file, "rw"); -- if (this.c.length() < 4096L) { -+ if (this.c.length() < 8192L) { // Paper - headers should be 8192 - this.c.write(RegionFile.a); - this.c.write(RegionFile.a); - this.g += 8192; -@@ -0,0 +0,0 @@ public class RegionFile { - this.c.seek(j * 4 + 4); // Go back to where we were - } + public RegionFile(File file) throws IOException { + this.b = new RandomAccessFile(file, "rw"); +- if (this.b.length() < 4096L) { ++ if (this.b.length() < 8192L) { // Paper - headers should be 8192 + this.b.write(RegionFile.a); + this.b.write(RegionFile.a); + } +@@ -0,0 +0,0 @@ public class RegionFile implements AutoCloseable { + this.b.seek(j * 4 + 4); // Go back to where we were } -- if (k != 0 && (k >> 8) + (length) <= this.f.size()) { -+ if (k > 0 && (k >> 8) > 1 && (k >> 8) + (k & 255) <= this.f.size()) { // Paper >= 1 as 0/1 are the headers, and negative isnt valid - for (int l = 0; l < (length); ++l) { - // Spigot end - this.f.set((k >> 8) + l, false); - } - } - // Spigot start -- else if (length > 0) { -- org.bukkit.Bukkit.getLogger().log(java.util.logging.Level.WARNING, "Invalid chunk: ({0}, {1}) Offset: {2} Length: {3} runs off end file. {4}", new Object[]{j % 32, (int) (j / 32), k >> 8, length, file}); -+ else if (k != 0) { // Paper -+ org.bukkit.Bukkit.getLogger().log(java.util.logging.Level.SEVERE, "Invalid chunk: ({0}, {1}) Offset: {2} Length: {3} runs off end file. {4}", new Object[]{j % 32, (int) (j / 32), k >> 8, length, file}); // Paper -+ deleteChunk(j); // Paper - } - // Spigot end } - - for (j = 0; j < 1024; ++j) { - k = headerAsInts.get(); // Paper -- this.e[j] = k; -+ if (offsets[j] != 0) this.timestamps[j] = k; // Paper - don't set timestamp if it got 0'd above due to corruption +- if (k != 0 && (k >> 8) + (length) <= this.e.size()) { ++ if (k > 0 && (k >> 8) > 1 && (k >> 8) + (k & 255) <= this.e.size()) { // Paper >= 1 as 0/1 are the headers, and negative isnt valid + for (int l = 0; l < (length); ++l) { + // Spigot end + this.e.set((k >> 8) + l, false); +@@ -0,0 +0,0 @@ public class RegionFile implements AutoCloseable { + // Spigot start + else if (length > 0) { + org.bukkit.Bukkit.getLogger().log(java.util.logging.Level.WARNING, "Invalid chunk: ({0}, {1}) Offset: {2} Length: {3} runs off end file. {4}", new Object[]{j % 32, (int) (j / 32), k >> 8, length, file}); ++ deleteChunk(j); // Paper } - } catch (IOException ioexception) { - ioexception.printStackTrace(); -@@ -0,0 +0,0 @@ public class RegionFile { - int j1 = this.c.readInt(); + // Spigot end + } - if (j1 > 4096 * i1) { -- org.bukkit.Bukkit.getLogger().log(java.util.logging.Level.WARNING, "Invalid chunk: ({0}, {1}) Offset: {2} Invalid Size: {3}>{4} {5}", new Object[]{i, j, l, j1, i1 * 4096, this.b}); // Spigot -+ org.bukkit.Bukkit.getLogger().log(java.util.logging.Level.SEVERE, "Invalid chunk: ({0}, {1}) Offset: {2} Invalid Size: {3}>{4} {5}", new Object[]{i, j, l, j1, i1 * 4096, this.b}); // Spigot - return null; - } else if (j1 <= 0) { -- org.bukkit.Bukkit.getLogger().log(java.util.logging.Level.WARNING, "Invalid chunk: ({0}, {1}) Offset: {2} Invalid Size: {3} {4}", new Object[]{i, j, l, j1, this.b}); // Spigot -+ org.bukkit.Bukkit.getLogger().log(java.util.logging.Level.SEVERE, "Invalid chunk: ({0}, {1}) Offset: {2} Invalid Size: {3} {4}", new Object[]{i, j, l, j1, this.b}); // Spigot - return null; - } else { - byte b0 = this.c.readByte(); -@@ -0,0 +0,0 @@ public class RegionFile { + for (j = 0; j < 1024; ++j) { + k = headerAsInts.get(); // Paper +- this.d[j] = k; ++ if (offsets[j] != 0) this.timestamps[j] = k; // Paper - don't set timestamp if it got 0'd above due to corruption + } + this.file = file; // Spigot +@@ -0,0 +0,0 @@ public class RegionFile implements AutoCloseable { + this.b.close(); } + // Paper start @@ -101,10 +78,10 @@ index e2d4450e90..c20511588d 100644 + // clear the timestamp + file.seek(4096 + j1 * 4); + file.writeInt(0); -+ org.bukkit.Bukkit.getLogger().log(java.util.logging.Level.SEVERE, "Deleted corrupt chunk (" + debug + ") " + getFile().getAbsolutePath(), e); ++ org.bukkit.Bukkit.getLogger().log(java.util.logging.Level.SEVERE, "Deleted corrupt chunk (" + debug + ") " + this.file.getAbsolutePath(), e); + } catch (IOException e) { + -+ org.bukkit.Bukkit.getLogger().log(java.util.logging.Level.SEVERE, "Error deleting corrupt chunk (" + debug + ") " + getFile().getAbsolutePath(), e); ++ org.bukkit.Bukkit.getLogger().log(java.util.logging.Level.SEVERE, "Error deleting corrupt chunk (" + debug + ") " + this.file.getAbsolutePath(), e); + } + } + private boolean backedUp = false; @@ -113,7 +90,6 @@ index e2d4450e90..c20511588d 100644 + return; + } + backedUp = true; -+ File file = this.getFile(); + java.text.DateFormat formatter = new java.text.SimpleDateFormat("yyyy-MM-dd"); + java.util.Date today = new java.util.Date(); + File corrupt = new File(file.getParentFile(), file.getName() + "." + formatter.format(today) + ".corrupt"); @@ -133,5 +109,5 @@ index e2d4450e90..c20511588d 100644 + class ChunkBuffer extends ByteArrayOutputStream { - private final int b; + private final ChunkCoordIntPair b; -- \ No newline at end of file diff --git a/Spigot-Server-Patches/Entity-add-to-world-fixes.patch b/Spigot-Server-Patches/Entity-add-to-world-fixes.patch deleted file mode 100644 index 28ac97ee57..0000000000 --- a/Spigot-Server-Patches/Entity-add-to-world-fixes.patch +++ /dev/null @@ -1,94 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Aikar -Date: Fri, 3 Aug 2018 22:47:46 -0400 -Subject: [PATCH] Entity add to world fixes - -1) Chunk Registration might kill an entity, don't add it to the world if it did! - -2) By default, entities are added to the world per slice iteration. -This opens risk of the slices being manipulated during chunk add if an -EntityAddToWorldEvent spawns an entity into this chunk. -Fix this by differing entity add to world for all entities at the same time - -3) If a duplicate entity is attempted to add to the world of an entity, and -the original entity is dead, overwrite it as the logic does for unloaod queued entities. - -diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java -index 01abe5e376..4502ece4dd 100644 ---- a/src/main/java/net/minecraft/server/Chunk.java -+++ b/src/main/java/net/minecraft/server/Chunk.java -@@ -0,0 +0,0 @@ package net.minecraft.server; - - // Paper start - import com.destroystokyo.paper.PaperWorldConfig.DuplicateUUIDMode; -+ -+import java.util.Arrays; - import java.util.HashMap; - import java.util.UUID; - // Paper end -@@ -0,0 +0,0 @@ public class Chunk implements IChunkAccess { - // Paper end - - // CraftBukkit start -- List toRemove = new LinkedList<>(); -- this.world.a(entityslice.stream().filter((entity) -> { -- if (this.needsDecoration && !CraftEventFactory.doEntityAddEventCalling(this.world, entity, CreatureSpawnEvent.SpawnReason.CHUNK_GEN)) { // Only call for new chunks -- toRemove.add(entity); -- return false; -- } -- return !(entity instanceof EntityHuman); -- })); -- entityslice.removeAll(toRemove); -+ this.world.addChunkEntities(entityslice.stream() // Paper - add all at same time to avoid entities adding to world modifying slice state, skip already added entities (not normal, but can happen) -+ // Paper start - Inline event into stream -+ .filter((entity) -> { -+ if (!this.needsDecoration) { -+ return true; -+ } -+ return CraftEventFactory.doEntityAddEventCalling(this.world, entity, CreatureSpawnEvent.SpawnReason.CHUNK_GEN); -+ }) -+ // Paper end - Inline event into stream -+ .filter((entity) -> !(entity instanceof EntityHuman || entity.valid))); // Paper - add all at same time to avoid entities adding to world modifying slice state, skip already added entities (not normal, but can happen) - // CraftBukkit end - } - -diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index 3acea908c2..e31e366249 100644 ---- a/src/main/java/net/minecraft/server/World.java -+++ b/src/main/java/net/minecraft/server/World.java -@@ -0,0 +0,0 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc - } - - this.getChunkAt(i, j).a(entity); -+ if (entity.dead) return false; // Paper - don't add dead entities, chunk registration may of killed it - this.entityList.add(entity); - this.b(entity); - return true; -@@ -0,0 +0,0 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc - return j; - } - -+ public void addChunkEntities(Stream collection) { a(collection); } // Paper - OBFHELPER - public void a(Stream stream) { - org.spigotmc.AsyncCatcher.catchOp( "entity world add"); // Spigot - stream.forEach((entity) -> { -+ if (entity == null || entity.dead || entity.valid) { // Paper - prevent adding already added or dead entities -+ return; -+ } - this.entityList.add(entity); - this.b(entity); - }); -diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index 293818b196..4cda6cee2b 100644 ---- a/src/main/java/net/minecraft/server/WorldServer.java -+++ b/src/main/java/net/minecraft/server/WorldServer.java -@@ -0,0 +0,0 @@ public class WorldServer extends World implements IAsyncTaskHandler { - if (this.entitiesByUUID.containsKey(uuid)) { - Entity entity1 = (Entity) this.entitiesByUUID.get(uuid); - -- if (this.g.contains(entity1)) { -+ if (this.g.contains(entity1) || entity1.dead) { // Paper - if dupe is dead, overwrite - this.g.remove(entity1); - } else { - if (!(entity instanceof EntityHuman)) { --- \ No newline at end of file diff --git a/Spigot-Server-Patches/Fix-client-rendering-skulls-from-same-user.patch b/Spigot-Server-Patches/Fix-client-rendering-skulls-from-same-user.patch index 8ebce400a1..a6b492f95a 100644 --- a/Spigot-Server-Patches/Fix-client-rendering-skulls-from-same-user.patch +++ b/Spigot-Server-Patches/Fix-client-rendering-skulls-from-same-user.patch @@ -12,7 +12,7 @@ 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/server/ItemStack.java b/src/main/java/net/minecraft/server/ItemStack.java -index c1b6eb52bf..0420589faa 100644 +index 2acd02f2f..ca1bd0299 100644 --- a/src/main/java/net/minecraft/server/ItemStack.java +++ b/src/main/java/net/minecraft/server/ItemStack.java @@ -0,0 +0,0 @@ public final class ItemStack { @@ -25,7 +25,7 @@ index c1b6eb52bf..0420589faa 100644 private EntityItemFrame i; private ShapeDetectorBlock j; diff --git a/src/main/java/net/minecraft/server/PacketDataSerializer.java b/src/main/java/net/minecraft/server/PacketDataSerializer.java -index d05f1e02cf..b95836d443 100644 +index 0d67676f7..fa2d3ce8c 100644 --- a/src/main/java/net/minecraft/server/PacketDataSerializer.java +++ b/src/main/java/net/minecraft/server/PacketDataSerializer.java @@ -0,0 +0,0 @@ public class PacketDataSerializer extends ByteBuf { @@ -45,7 +45,7 @@ index d05f1e02cf..b95836d443 100644 this.a(nbttagcompound); @@ -0,0 +0,0 @@ public class PacketDataSerializer extends ByteBuf { - itemstack.setTag(this.j()); + itemstack.setTag(this.l()); // CraftBukkit start if (itemstack.getTag() != null) { + // Paper start - Fix skulls of same owner - restore orig ID since we changed it on send to client @@ -62,32 +62,27 @@ index d05f1e02cf..b95836d443 100644 } // CraftBukkit end diff --git a/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java b/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java -index f2159bc2dd..18ef7232ec 100644 +index 363ab5da1..d19a30ad8 100644 --- a/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java +++ b/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java @@ -0,0 +0,0 @@ public class PacketPlayOutMapChunk implements Packet { if (this.f() || (i & 1 << j) != 0) { - NBTTagCompound nbttagcompound = tileentity.aa_(); + NBTTagCompound nbttagcompound = tileentity.b(); + if (tileentity instanceof TileEntitySkull) { TileEntitySkull.sanitizeTileEntityUUID(nbttagcompound); } // Paper - this.e.add(nbttagcompound); + this.f.add(nbttagcompound); } -@@ -0,0 +0,0 @@ public class PacketPlayOutMapChunk implements Packet { - BiomeBase[] abiomebase = chunk.getBiomeIndex(); - - for (l = 0; l < abiomebase.length; ++l) { -- packetdataserializer.writeInt(IRegistry.BIOME.a((Object) abiomebase[l])); -+ packetdataserializer.writeInt(IRegistry.BIOME.a(abiomebase[l])); // Paper - Decompile fix - } - } - diff --git a/src/main/java/net/minecraft/server/TileEntitySkull.java b/src/main/java/net/minecraft/server/TileEntitySkull.java -index 79c24cdc4c..6511bfda8d 100644 +index e827d7605..4803b173a 100644 --- a/src/main/java/net/minecraft/server/TileEntitySkull.java +++ b/src/main/java/net/minecraft/server/TileEntitySkull.java @@ -0,0 +0,0 @@ public class TileEntitySkull extends TileEntity /*implements ITickable*/ { // Pa - return this.a; + @Nullable + @Override + public PacketPlayOutTileEntityData getUpdatePacket() { +- return new PacketPlayOutTileEntityData(this.position, 4, this.b()); ++ return new PacketPlayOutTileEntityData(this.position, 4, sanitizeTileEntityUUID(this.b())); // Paper } + // Paper start @@ -118,11 +113,7 @@ index 79c24cdc4c..6511bfda8d 100644 + } + // Paper end + - @Nullable - public PacketPlayOutTileEntityData getUpdatePacket() { -- return new PacketPlayOutTileEntityData(this.position, 4, this.aa_()); -+ return new PacketPlayOutTileEntityData(this.position, 4, sanitizeTileEntityUUID(this.aa_())); // Paper - } - - public NBTTagCompound aa_() { + @Override + public NBTTagCompound b() { + return this.save(new NBTTagCompound()); -- \ No newline at end of file diff --git a/Spigot-Server-Patches/Ignore-Dead-Entities-in-entityList-iteration.patch b/Spigot-Server-Patches/Ignore-Dead-Entities-in-entityList-iteration.patch index 62809b5852..81a2998efe 100644 --- a/Spigot-Server-Patches/Ignore-Dead-Entities-in-entityList-iteration.patch +++ b/Spigot-Server-Patches/Ignore-Dead-Entities-in-entityList-iteration.patch @@ -11,7 +11,7 @@ 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 f38179e983..8e1bda4de9 100644 +index f38179e98..8e1bda4de 100644 --- a/src/main/java/com/destroystokyo/paper/PaperCommand.java +++ b/src/main/java/com/destroystokyo/paper/PaperCommand.java @@ -0,0 +0,0 @@ public class PaperCommand extends Command { @@ -22,60 +22,81 @@ index f38179e983..8e1bda4de9 100644 MutablePair> info = list.computeIfAbsent(key, k -> MutablePair.of(0, Maps.newHashMap())); ChunkCoordIntPair chunk = new ChunkCoordIntPair(e.getChunkX(), e.getChunkZ()); +diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java +index 0c8a2ac90..21fae98c1 100644 +--- a/src/main/java/net/minecraft/server/Chunk.java ++++ b/src/main/java/net/minecraft/server/Chunk.java +@@ -0,0 +0,0 @@ public class Chunk implements IChunkAccess { + + while (iterator.hasNext()) { + Entity entity1 = (Entity) iterator.next(); ++ if (entity1.shouldBeRemoved) continue; // Paper + + if (entity1.getBoundingBox().c(axisalignedbb) && entity1 != entity) { + if (predicate == null || predicate.test(entity1)) { +@@ -0,0 +0,0 @@ public class Chunk implements IChunkAccess { + + while (iterator.hasNext()) { + Entity entity = (Entity) iterator.next(); ++ if (entity.shouldBeRemoved) continue; // Paper + + if ((entitytypes == null || entity.getEntityType() == entitytypes) && entity.getBoundingBox().c(axisalignedbb) && predicate.test(entity)) { + list.add(entity); +@@ -0,0 +0,0 @@ public class Chunk implements IChunkAccess { + + while (iterator.hasNext()) { + T t0 = (T) iterator.next(); // CraftBukkit - decompile error ++ if (t0.shouldBeRemoved) continue; // Paper + + if (oclass.isInstance(t0) && t0.getBoundingBox().c(axisalignedbb) && (predicate == null || predicate.test(t0))) { // Spigot - instance check + list.add(t0); diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java -index ead5af991c..cf69a4d8a4 100644 +index 4648a93b0..99abf7f9c 100644 --- a/src/main/java/net/minecraft/server/Entity.java +++ b/src/main/java/net/minecraft/server/Entity.java @@ -0,0 +0,0 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke - protected boolean F; - private boolean az; public boolean dead; + public float D; + public float E; +- public float F; + public boolean shouldBeRemoved; // Paper - public float width; - public float length; - public float J; -diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index 1cbe6e17b7..5d60b36678 100644 ---- a/src/main/java/net/minecraft/server/World.java -+++ b/src/main/java/net/minecraft/server/World.java -@@ -0,0 +0,0 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc - } + public float fallDistance; + private float av; + private float aw; +diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java +index 3e41c080d..3bfe40bb6 100644 +--- a/src/main/java/net/minecraft/server/WorldServer.java ++++ b/src/main/java/net/minecraft/server/WorldServer.java +@@ -0,0 +0,0 @@ public class WorldServer extends World { - entity.valid = true; // CraftBukkit -+ 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 - } - -@@ -0,0 +0,0 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc - - Chunk chunk = entity.getCurrentChunk(); // Paper - if (chunk != null) chunk.removeEntity(entity); // Paper -+ entity.shouldBeRemoved = true; // Paper - - if (!guardEntityList) { // Spigot - It will get removed after the tick if we are ticking // Paper - always remove from current chunk above - // CraftBukkit start - Decrement loop variable field if we've already ticked this entity -@@ -0,0 +0,0 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc - - while (iterator.hasNext()) { - Entity entity = (Entity) iterator.next(); -+ if (entity.shouldBeRemoved) continue; // Paper - - if (oclass.isAssignableFrom(entity.getClass()) && predicate.test((T) entity)) { // CraftBukkit - decompile error - list.add((T) entity); // CraftBukkit - decompile error -@@ -0,0 +0,0 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc - - while (iterator.hasNext()) { - Entity entity = (Entity) iterator.next(); + while (objectiterator.hasNext()) { + Entity entity = (Entity) objectiterator.next(); + if (entity.shouldBeRemoved) continue; // Paper // CraftBukkit start - Split out persistent check, don't apply it to special persistent mobs if (entity instanceof EntityInsentient) { EntityInsentient entityinsentient = (EntityInsentient) entity; +@@ -0,0 +0,0 @@ public class WorldServer extends World { + this.I.add(((EntityInsentient) entity).getNavigation()); + } + entity.valid = true; // CraftBukkit ++ 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 + } + +@@ -0,0 +0,0 @@ public class WorldServer extends World { + this.removeEntityFromChunk(entity); + this.entitiesById.remove(entity.getId()); + this.unregisterEntity(entity); ++ entity.shouldBeRemoved = true; // Paper + } + } + diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 609b911265..4594bab465 100644 +index f8870f37b..03148879f 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -0,0 +0,0 @@ public class CraftWorld implements World { - for (Object o : world.entityList) { + for (Object o : world.entitiesById.values()) { if (o instanceof net.minecraft.server.Entity) { net.minecraft.server.Entity mcEnt = (net.minecraft.server.Entity) o; + if (mcEnt.shouldBeRemoved) continue; // Paper @@ -83,7 +104,7 @@ index 609b911265..4594bab465 100644 // Assuming that bukkitEntity isn't null @@ -0,0 +0,0 @@ public class CraftWorld implements World { - for (Object o : world.entityList) { + for (Object o : world.entitiesById.values()) { if (o instanceof net.minecraft.server.Entity) { net.minecraft.server.Entity mcEnt = (net.minecraft.server.Entity) o; + if (mcEnt.shouldBeRemoved) continue; // Paper @@ -92,7 +113,7 @@ index 609b911265..4594bab465 100644 // Assuming that bukkitEntity isn't null @@ -0,0 +0,0 @@ public class CraftWorld implements World { - for (Object entity: world.entityList) { + for (Object entity: world.entitiesById.values()) { if (entity instanceof net.minecraft.server.Entity) { + if (((net.minecraft.server.Entity) entity).shouldBeRemoved) continue; // Paper Entity bukkitEntity = ((net.minecraft.server.Entity) entity).getBukkitEntity(); @@ -100,7 +121,7 @@ index 609b911265..4594bab465 100644 if (bukkitEntity == null) { @@ -0,0 +0,0 @@ public class CraftWorld implements World { - for (Object entity: world.entityList) { + for (Object entity: world.entitiesById.values()) { if (entity instanceof net.minecraft.server.Entity) { + if (((net.minecraft.server.Entity) entity).shouldBeRemoved) continue; // Paper Entity bukkitEntity = ((net.minecraft.server.Entity) entity).getBukkitEntity(); diff --git a/Spigot-Server-Patches/Implement-Expanded-ArmorStand-API.patch b/Spigot-Server-Patches/Implement-Expanded-ArmorStand-API.patch index a6218ffa31..4af81bea88 100644 --- a/Spigot-Server-Patches/Implement-Expanded-ArmorStand-API.patch +++ b/Spigot-Server-Patches/Implement-Expanded-ArmorStand-API.patch @@ -8,28 +8,28 @@ Add the following: - Enable/Disable slot interactions diff --git a/src/main/java/net/minecraft/server/EntityArmorStand.java b/src/main/java/net/minecraft/server/EntityArmorStand.java -index 694df9e185..c604182dd9 100644 +index f8cd62199..8fb3ce17a 100644 --- a/src/main/java/net/minecraft/server/EntityArmorStand.java +++ b/src/main/java/net/minecraft/server/EntityArmorStand.java @@ -0,0 +0,0 @@ public class EntityArmorStand extends EntityLiving { - private final NonNullList bF; - private boolean bG; - public long h; -- private int bH; -+ private int bH;public void setDisabledSlots(int i) { bH = i;} public int getDisabledSlots() { return bH ;} // Paper - OBFHELPER - private boolean bI; + private final NonNullList armorItems; + private boolean bD; + public long bt; +- private int bE; ++ private int bE; public void setDisabledSlots(int i) { bE = i;} public int getDisabledSlots() { return bE ;} // Paper - OBFHELPER public Vector3f headPose; public Vector3f bodyPose; + public Vector3f leftArmPose; @@ -0,0 +0,0 @@ public class EntityArmorStand extends EntityLiving { return enumitemslot; } -+ public boolean isSlotDisabled(EnumItemSlot slot) { return this.c(slot); } // Paper - OBFHELPER - public boolean c(EnumItemSlot enumitemslot) { - return (this.bH & 1 << enumitemslot.c()) != 0 || enumitemslot.a() == EnumItemSlot.Function.HAND && !this.hasArms(); ++ public boolean isSlotDisabled(EnumItemSlot slot) { return this.d(slot); } // Paper - OBFHELPER + public boolean d(EnumItemSlot enumitemslot) { + return (this.bE & 1 << enumitemslot.c()) != 0 || enumitemslot.a() == EnumItemSlot.Function.HAND && !this.hasArms(); } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java -index 124c3185bc..9f5c3b92e3 100644 +index 124c3185b..9f5c3b92e 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java @@ -0,0 +0,0 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand { diff --git a/Spigot-Server-Patches/MC-111480-Start-Entity-ID-s-at-1.patch b/Spigot-Server-Patches/MC-111480-Start-Entity-ID-s-at-1.patch index 10f8db1f51..5fc644bb3c 100644 --- a/Spigot-Server-Patches/MC-111480-Start-Entity-ID-s-at-1.patch +++ b/Spigot-Server-Patches/MC-111480-Start-Entity-ID-s-at-1.patch @@ -7,16 +7,16 @@ DataWatchers that store Entity ID's treat 0 as special, and can break things such as Elytra Fireworks. diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java -index cf69a4d8a4..4dc7c8ba68 100644 +index 99abf7f9c..2dfa7d251 100644 --- a/src/main/java/net/minecraft/server/Entity.java +++ b/src/main/java/net/minecraft/server/Entity.java @@ -0,0 +0,0 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke - private static final List a = Collections.emptyList(); - private static final AxisAlignedBB b = new AxisAlignedBB(0.0D, 0.0D, 0.0D, 0.0D, 0.0D, 0.0D); - private static double c = 1.0D; -- private static int entityCount; -+ private static int entityCount = 1; // Paper - MC-111480 - ID 0 is treated as special for DataWatchers, start 1 - private final EntityTypes g; public EntityTypes getEntityType() { return g; } // Paper - OBFHELPER - private int id; - public boolean j; public boolean blocksEntitySpawning() { return j; } // Paper - OBFHELPER + // CraftBukkit end + + protected static final Logger LOGGER = LogManager.getLogger(); +- private static final AtomicInteger entityCount = new AtomicInteger(); ++ private static final AtomicInteger entityCount = new AtomicInteger(1); // paper - start entity count from 1 + private static final List c = Collections.emptyList(); + private static final AxisAlignedBB d = new AxisAlignedBB(0.0D, 0.0D, 0.0D, 0.0D, 0.0D, 0.0D); + private static double e = 1.0D; -- \ No newline at end of file diff --git a/Spigot-Server-Patches/MC-135506-Experience-should-save-as-Integers.patch b/Spigot-Server-Patches/MC-135506-Experience-should-save-as-Integers.patch index d75feb31bd..33d2fcd625 100644 --- a/Spigot-Server-Patches/MC-135506-Experience-should-save-as-Integers.patch +++ b/Spigot-Server-Patches/MC-135506-Experience-should-save-as-Integers.patch @@ -5,24 +5,25 @@ Subject: [PATCH] MC-135506: Experience should save as Integers diff --git a/src/main/java/net/minecraft/server/EntityExperienceOrb.java b/src/main/java/net/minecraft/server/EntityExperienceOrb.java -index 09d85764b0..3606b10143 100644 +index 64d71a9a2..65c996961 100644 --- a/src/main/java/net/minecraft/server/EntityExperienceOrb.java +++ b/src/main/java/net/minecraft/server/EntityExperienceOrb.java @@ -0,0 +0,0 @@ public class EntityExperienceOrb extends Entity { public void b(NBTTagCompound nbttagcompound) { - nbttagcompound.setShort("Health", (short) this.d); - nbttagcompound.setShort("Age", (short) this.b); + nbttagcompound.setShort("Health", (short) this.e); + nbttagcompound.setShort("Age", (short) this.c); - nbttagcompound.setShort("Value", (short) this.value); + nbttagcompound.setInt("Value", this.value); // Paper - save as Integer - savePaperNBT(nbttagcompound); // Paper + this.savePaperNBT(nbttagcompound); // Paper } +@@ -0,0 +0,0 @@ public class EntityExperienceOrb extends Entity { public void a(NBTTagCompound nbttagcompound) { - this.d = nbttagcompound.getShort("Health"); - this.b = nbttagcompound.getShort("Age"); + this.e = nbttagcompound.getShort("Health"); + this.c = nbttagcompound.getShort("Age"); - this.value = nbttagcompound.getShort("Value"); + this.value = nbttagcompound.getInt("Value"); // Paper - load as Integer - loadPaperNBT(nbttagcompound); // Paper + this.loadPaperNBT(nbttagcompound); // Paper } -- \ No newline at end of file diff --git a/Spigot-Server-Patches/Make-EnderDragon-implement-Mob.patch b/Spigot-Server-Patches/Make-EnderDragon-implement-Mob.patch index a1c858da6a..46a73bcd79 100644 --- a/Spigot-Server-Patches/Make-EnderDragon-implement-Mob.patch +++ b/Spigot-Server-Patches/Make-EnderDragon-implement-Mob.patch @@ -5,7 +5,7 @@ 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 cc115cc368..4947249da2 100644 +index cc115cc36..4947249da 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftComplexLivingEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftComplexLivingEntity.java @@ -0,0 +0,0 @@ diff --git a/Spigot-Server-Patches/Make-portal-teleportation-adjustment-math-more-accur.patch b/Spigot-Server-Patches/Make-portal-teleportation-adjustment-math-more-accur.patch deleted file mode 100644 index 1ea48a4a47..0000000000 --- a/Spigot-Server-Patches/Make-portal-teleportation-adjustment-math-more-accur.patch +++ /dev/null @@ -1,93 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Zach Brown <1254957+zachbr@users.noreply.github.com> -Date: Tue, 31 Jul 2018 19:32:57 -0500 -Subject: [PATCH] Make portal teleportation adjustment math more accurate - - -diff --git a/src/main/java/net/minecraft/server/EnumDirection.java b/src/main/java/net/minecraft/server/EnumDirection.java -index 13f0fb0b67..ce71811271 100644 ---- a/src/main/java/net/minecraft/server/EnumDirection.java -+++ b/src/main/java/net/minecraft/server/EnumDirection.java -@@ -0,0 +0,0 @@ public enum EnumDirection implements INamable { - return this.i; - } - -+ public final EnumDirection.EnumAxisDirection getAxisDirection() { return c(); } // Paper - OBFHELPER - public EnumDirection.EnumAxisDirection c() { - return this.l; - } -@@ -0,0 +0,0 @@ public enum EnumDirection implements INamable { - return fromType1(this.h); - } - -+ public final EnumDirection rotateY() { return e(); } // Paper - OBFHELPER - public EnumDirection e() { - switch (this) { - case NORTH: -@@ -0,0 +0,0 @@ public enum EnumDirection implements INamable { - this.d = s; - } - -+ public final int getOffset() { return a(); } // Paper - OBFHELPER - public int a() { - return this.c; - } -diff --git a/src/main/java/net/minecraft/server/MathHelper.java b/src/main/java/net/minecraft/server/MathHelper.java -index 52918b971f..8bb2593aa9 100644 ---- a/src/main/java/net/minecraft/server/MathHelper.java -+++ b/src/main/java/net/minecraft/server/MathHelper.java -@@ -0,0 +0,0 @@ public class MathHelper { - return f < f1 ? f1 : (f > f2 ? f2 : f); - } - -+ public static double clamp(double d0, double d1, double d2) { return a(d0, d1, d2); } // Paper - OBFHELPER - public static double a(double d0, double d1, double d2) { - return d0 < d1 ? d1 : (d0 > d2 ? d2 : d0); - } -diff --git a/src/main/java/net/minecraft/server/PortalTravelAgent.java b/src/main/java/net/minecraft/server/PortalTravelAgent.java -index a24bd02d5b..d30a8a6bdd 100644 ---- a/src/main/java/net/minecraft/server/PortalTravelAgent.java -+++ b/src/main/java/net/minecraft/server/PortalTravelAgent.java -@@ -0,0 +0,0 @@ public class PortalTravelAgent { - ++d4; - } - -+ // Paper start - Prevent portal suffocation (and therefore getting teleported up in an attempt to avoid it) -+ // Based on work by CarpetMod - Licensed GPL-3.0 -+ double offset = (1.0D - entity.getPortalOffset().x) * (double) shapedetector_shapedetectorcollection.getWidth() * (double) shapedetector_shapedetectorcollection.getFacing().rotateY().getAxisDirection().getOffset(); -+ double adjustedRadius = 1.02 * entity.width / 2; -+ if (adjustedRadius >= shapedetector_shapedetectorcollection.getWidth() - adjustedRadius) { -+ // entity wider than portal, place it in the middle -+ adjustedRadius = (double) shapedetector_shapedetectorcollection.getWidth() / 2 - 0.001; -+ } -+ -+ if (offset >= 0) { -+ offset = MathHelper.clamp(offset, adjustedRadius, (double) shapedetector_shapedetectorcollection.getWidth() - adjustedRadius); -+ } else { -+ offset = MathHelper.clamp(offset, (double) -shapedetector_shapedetectorcollection.getWidth() + adjustedRadius, -adjustedRadius); -+ } -+ - if (shapedetector_shapedetectorcollection.getFacing().k() == EnumDirection.EnumAxis.X) { -- d3 = d4 + (1.0D - entity.getPortalOffset().x) * (double) shapedetector_shapedetectorcollection.d() * (double) shapedetector_shapedetectorcollection.getFacing().e().c().a(); -+ d3 = d4 + offset; - } else { -- d2 = d4 + (1.0D - entity.getPortalOffset().x) * (double) shapedetector_shapedetectorcollection.d() * (double) shapedetector_shapedetectorcollection.getFacing().e().c().a(); -+ d2 = d4 + offset; - } -+ // Paper end - - float f1 = 0.0F; - float f2 = 0.0F; -diff --git a/src/main/java/net/minecraft/server/ShapeDetector.java b/src/main/java/net/minecraft/server/ShapeDetector.java -index 8ba4da0ea0..8716f5fd95 100644 ---- a/src/main/java/net/minecraft/server/ShapeDetector.java -+++ b/src/main/java/net/minecraft/server/ShapeDetector.java -@@ -0,0 +0,0 @@ public class ShapeDetector { - return this.c; - } - -+ public final int getWidth() { return this.d(); } // Paper - OBFHELPER - public int d() { - return this.e; - } --- \ No newline at end of file diff --git a/Spigot-Server-Patches/Optimize-BlockPosition-helper-methods.patch b/Spigot-Server-Patches/Optimize-BlockPosition-helper-methods.patch index 6514b09468..41be29ebe3 100644 --- a/Spigot-Server-Patches/Optimize-BlockPosition-helper-methods.patch +++ b/Spigot-Server-Patches/Optimize-BlockPosition-helper-methods.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Optimize BlockPosition helper methods Resolves #1338 diff --git a/src/main/java/net/minecraft/server/BlockPosition.java b/src/main/java/net/minecraft/server/BlockPosition.java -index 20cf9255ba..5ce18f54c6 100644 +index a5e5a4eba..6ed584f8d 100644 --- a/src/main/java/net/minecraft/server/BlockPosition.java +++ b/src/main/java/net/minecraft/server/BlockPosition.java -@@ -0,0 +0,0 @@ public class BlockPosition extends BaseBlockPosition { +@@ -0,0 +0,0 @@ public class BlockPosition extends BaseBlockPosition implements MinecraftSeriali } public BlockPosition up() { diff --git a/Spigot-Server-Patches/Optimize-Hoppers.patch b/Spigot-Server-Patches/Optimize-Hoppers.patch index d795e021aa..33c4a0d61b 100644 --- a/Spigot-Server-Patches/Optimize-Hoppers.patch +++ b/Spigot-Server-Patches/Optimize-Hoppers.patch @@ -11,7 +11,7 @@ Subject: [PATCH] Optimize Hoppers * Skip subsequent InventoryMoveItemEvents if a plugin does not use the item after first event fire for an iteration diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -index 0b60ca82ce..e87fb94c06 100644 +index a5b4f9990..2b5402b00 100644 --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java +++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java @@ -0,0 +0,0 @@ public class PaperWorldConfig { @@ -31,7 +31,7 @@ index 0b60ca82ce..e87fb94c06 100644 private void disableSprintInterruptionOnAttack() { disableSprintInterruptionOnAttack = getBoolean("game-mechanics.disable-sprint-interruption-on-attack", false); diff --git a/src/main/java/net/minecraft/server/ItemStack.java b/src/main/java/net/minecraft/server/ItemStack.java -index 0420589faa..0d06db9355 100644 +index ca1bd0299..2d83c9e79 100644 --- a/src/main/java/net/minecraft/server/ItemStack.java +++ b/src/main/java/net/minecraft/server/ItemStack.java @@ -0,0 +0,0 @@ public final class ItemStack { @@ -44,22 +44,22 @@ index 0420589faa..0d06db9355 100644 + public ItemStack cloneItemStack(boolean origItem) { // Paper + ItemStack itemstack = new ItemStack(origItem ? this.item : this.getItem(), this.count); // Paper - itemstack.d(this.B()); + itemstack.d(this.C()); if (this.tag != null) { diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 4565a56b3f..38c0201acb 100644 +index 30952ade4..0cebf6f5a 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -0,0 +0,0 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati +@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant 0; // Paper + TileEntityHopper.skipHopperEvents = worldserver.paperConfig.disableHopperMoveEvents || org.bukkit.event.inventory.InventoryMoveItemEvent.getHandlerList().getRegisteredListeners().length == 0; // Paper i = SystemUtils.getMonotonicNanos(); if (true || worldserver.worldProvider.getDimensionManager() == DimensionManager.OVERWORLD || this.getAllowNether()) { // CraftBukkit this.methodProfiler.a(() -> { diff --git a/src/main/java/net/minecraft/server/TileEntity.java b/src/main/java/net/minecraft/server/TileEntity.java -index 29fe031d85..d67fd92d9d 100644 +index 4ac97a59c..6f63b2867 100644 --- a/src/main/java/net/minecraft/server/TileEntity.java +++ b/src/main/java/net/minecraft/server/TileEntity.java @@ -0,0 +0,0 @@ public abstract class TileEntity implements KeyedObject { // Paper @@ -75,11 +75,11 @@ index 29fe031d85..d67fd92d9d 100644 public void update() { if (this.world != null) { + if (IGNORE_TILE_UPDATES) return; // Paper - this.f = this.world.getType(this.position); + this.c = this.world.getType(this.position); this.world.b(this.position, this); - if (!this.f.isAir()) { + if (!this.c.isAir()) { diff --git a/src/main/java/net/minecraft/server/TileEntityHopper.java b/src/main/java/net/minecraft/server/TileEntityHopper.java -index 559eedfa66..7303a6fdda 100644 +index 0ecfbcb4b..dfe51fc6f 100644 --- a/src/main/java/net/minecraft/server/TileEntityHopper.java +++ b/src/main/java/net/minecraft/server/TileEntityHopper.java @@ -0,0 +0,0 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi @@ -234,11 +234,11 @@ index 559eedfa66..7303a6fdda 100644 + } + + // Paper end - private boolean s() { - IInventory iinventory = this.D(); + private boolean t() { + IInventory iinventory = this.u(); @@ -0,0 +0,0 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi - if (this.a(iinventory, enumdirection)) { + if (this.b(iinventory, enumdirection)) { return false; } else { + return hopperPush(iinventory, enumdirection); /* // Paper - disable rest @@ -255,13 +255,13 @@ index 559eedfa66..7303a6fdda 100644 } } @@ -0,0 +0,0 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi - if (b(iinventory, enumdirection)) { - return false; - } -+ skipPullModeEventFire = skipHopperEvents; // Paper + EnumDirection enumdirection = EnumDirection.DOWN; - if (iinventory instanceof IWorldInventory) { - IWorldInventory iworldinventory = (IWorldInventory) iinventory; + return c(iinventory, enumdirection) ? false : a(iinventory, enumdirection).anyMatch((i) -> { ++ skipPullModeEventFire = skipHopperEvents; // Paper + return a(ihopper, iinventory, i, enumdirection); + }); + } else { @@ -0,0 +0,0 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi ItemStack itemstack = iinventory.getItem(i); @@ -289,7 +289,7 @@ index 559eedfa66..7303a6fdda 100644 if (event.isCancelled()) { return false; @@ -0,0 +0,0 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi - boolean flag1 = iinventory1.P_(); + boolean flag1 = iinventory1.isNotEmpty(); if (itemstack1.isEmpty()) { + IGNORE_TILE_UPDATES = true; // Paper diff --git a/Spigot-Server-Patches/Provide-option-to-use-a-versioned-world-folder-for-t.patch b/Spigot-Server-Patches/Provide-option-to-use-a-versioned-world-folder-for-t.patch index 10e161f0f1..22f17da440 100644 --- a/Spigot-Server-Patches/Provide-option-to-use-a-versioned-world-folder-for-t.patch +++ b/Spigot-Server-Patches/Provide-option-to-use-a-versioned-world-folder-for-t.patch @@ -19,7 +19,7 @@ may be some delay there, but region files are only copied on demand. This is highly experiemental so backup your world before relying on this to not modify it diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java -index d42853d14c..63fdd94818 100644 +index c8f9c45e5..52adc671e 100644 --- a/src/main/java/com/destroystokyo/paper/PaperConfig.java +++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java @@ -0,0 +0,0 @@ import java.util.List; @@ -58,45 +58,31 @@ index d42853d14c..63fdd94818 100644 + } + } } -diff --git a/src/main/java/net/minecraft/server/ChunkRegionLoader.java b/src/main/java/net/minecraft/server/ChunkRegionLoader.java -index 485bce9872..60143ff63f 100644 ---- a/src/main/java/net/minecraft/server/ChunkRegionLoader.java -+++ b/src/main/java/net/minecraft/server/ChunkRegionLoader.java -@@ -0,0 +0,0 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver { - // private boolean f; // CraftBukkit - public final LongSet blacklist = new LongOpenHashSet(); - private static final double SAVE_QUEUE_TARGET_SIZE = 625; // Spigot -+ // Paper start - support saving to an alternate directory +diff --git a/src/main/java/net/minecraft/server/RegionFileCache.java b/src/main/java/net/minecraft/server/RegionFileCache.java +index c8573a8ee..1b12a1611 100644 +--- a/src/main/java/net/minecraft/server/RegionFileCache.java ++++ b/src/main/java/net/minecraft/server/RegionFileCache.java +@@ -0,0 +0,0 @@ import java.io.IOException; + import javax.annotation.Nullable; + import com.destroystokyo.paper.PaperConfig; // Paper + ++import org.apache.logging.log4j.LogManager; ++ + public abstract class RegionFileCache implements AutoCloseable { + + public final Long2ObjectLinkedOpenHashMap cache = new Long2ObjectLinkedOpenHashMap(); + private final File a; ++ // Paper start + private final File templateWorld; + private final File actualWorld; -+ private final boolean useAltWorld; -+ -+ private void copyIfNeeded(int x, int z) { -+ if (!useAltWorld) { -+ return; -+ } -+ synchronized (RegionFileCache.class) { -+ if (RegionFileCache.hasRegionFile(this.actualWorld, x, z)) { -+ return; -+ } -+ File actual = RegionFileCache.getRegionFileName(this.actualWorld, x, z); -+ File template = RegionFileCache.getRegionFileName(this.templateWorld, x, z); -+ if (!actual.exists() && template.exists()) { -+ try { -+ //a.info("Copying" + template + " to " + actual); -+ java.nio.file.Files.copy(template.toPath(), actual.toPath(), java.nio.file.StandardCopyOption.COPY_ATTRIBUTES); -+ } catch (IOException e1) { -+ LogManager.getLogger().error("Error copying " + template + " to " + actual, e1); -+ MinecraftServer.getServer().safeShutdown(); -+ com.destroystokyo.paper.util.SneakyThrow.sneaky(e1); -+ } -+ } -+ } -+ } ++ private boolean useAltWorld; + // Paper end ++ - public ChunkRegionLoader(File file, DataFixer datafixer) { -+ // Paper start + protected RegionFileCache(File file) { + this.a = file; ++ // Paper end ++ + this.actualWorld = file; + if (com.destroystokyo.paper.PaperConfig.useVersionedWorld) { + this.useAltWorld = true; @@ -114,57 +100,73 @@ index 485bce9872..60143ff63f 100644 + this.useAltWorld = false; + this.templateWorld = file; + } -+ // Paper end - this.c = file; - this.d = datafixer; - } -@@ -0,0 +0,0 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver { - } - - public boolean chunkExists(int x, int z) { -- return RegionFileCache.chunkExists(this.c, x, z); + // Paper start -+ if (this.saveMap.containsKey(ChunkCoordIntPair.asLong(x, z))) { -+ return true; -+ } -+ copyIfNeeded(x, z); -+ return RegionFileCache.chunkExists(this.actualWorld, x, z); -+ // Paper end } - @Nullable -@@ -0,0 +0,0 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver { - return null; - } - // CraftBukkit end -+ copyIfNeeded(i, j); // Paper -+ - NBTTagCompound nbttagcompound = SupplierUtils.getIfExists(this.saveMap.get(ChunkCoordIntPair.asLong(i, j))); // Spigot // Paper + private RegionFile a(ChunkCoordIntPair chunkcoordintpair, boolean existingOnly) throws IOException { // CraftBukkit +@@ -0,0 +0,0 @@ public abstract class RegionFileCache implements AutoCloseable { + this.a.mkdirs(); + } - if (nbttagcompound != null) { -diff --git a/src/main/java/net/minecraft/server/RegionFileCache.java b/src/main/java/net/minecraft/server/RegionFileCache.java -index d072222390..8c8b7cbab5 100644 ---- a/src/main/java/net/minecraft/server/RegionFileCache.java -+++ b/src/main/java/net/minecraft/server/RegionFileCache.java -@@ -0,0 +0,0 @@ public class RegionFileCache { - itr.remove(); ++ copyIfNeeded(chunkcoordintpair.x, chunkcoordintpair.z); // Paper + File file = new File(this.a, "r." + chunkcoordintpair.getRegionX() + "." + chunkcoordintpair.getRegionZ() + ".mca"); + if (existingOnly && !file.exists()) return null; // CraftBukkit + RegionFile regionfile1 = new RegionFile(file); +@@ -0,0 +0,0 @@ public abstract class RegionFileCache implements AutoCloseable { } } + + public static synchronized File getRegionFileName(File file, int i, int j) { + File file1 = new File(file, "region"); + return new File(file1, "r." + (i >> 5) + "." + (j >> 5) + ".mca"); + } -+ public static synchronized boolean hasRegionFile(File file, int i, int j) { -+ return RegionFileCache.cache.containsKey(getRegionFileName(file, i, j)); ++ public synchronized boolean hasRegionFile(File file, int i, int j) { ++ return cache.containsKey(getRegionFileName(file, i, j)); + } - // Paper End ++ // Paper End ++ + @Nullable + public NBTTagCompound read(ChunkCoordIntPair chunkcoordintpair) throws IOException { + RegionFile regionfile = this.a(chunkcoordintpair, false); // CraftBukkit +@@ -0,0 +0,0 @@ public abstract class RegionFileCache implements AutoCloseable { - public static synchronized void a() { + // CraftBukkit start + public boolean chunkExists(ChunkCoordIntPair pos) throws IOException { ++ copyIfNeeded(pos.x, pos.z); // Paper + RegionFile regionfile = a(pos, true); + + return regionfile != null ? regionfile.d(pos) : false; + } + // CraftBukkit end ++ ++ private void copyIfNeeded(int x, int z) { ++ if (!useAltWorld) { ++ return; ++ } ++ synchronized (RegionFileCache.class) { ++ if (hasRegionFile(this.actualWorld, x, z)) { ++ return; ++ } ++ File actual = RegionFileCache.getRegionFileName(this.actualWorld, x, z); ++ File template = RegionFileCache.getRegionFileName(this.templateWorld, x, z); ++ if (!actual.exists() && template.exists()) { ++ try { ++ net.minecraft.server.MinecraftServer.LOGGER.info("Copying" + template + " to " + actual); ++ java.nio.file.Files.copy(template.toPath(), actual.toPath(), java.nio.file.StandardCopyOption.COPY_ATTRIBUTES); ++ } catch (IOException e1) { ++ LogManager.getLogger().error("Error copying " + template + " to " + actual, e1); ++ MinecraftServer.getServer().safeShutdown(false); ++ com.destroystokyo.paper.util.SneakyThrow.sneaky(e1); ++ } ++ } ++ } ++ } + } diff --git a/src/main/java/net/minecraft/server/WorldNBTStorage.java b/src/main/java/net/minecraft/server/WorldNBTStorage.java -index 577ba1b5f9..9be0e994ef 100644 +index 350ac42d6..eaae44686 100644 --- a/src/main/java/net/minecraft/server/WorldNBTStorage.java +++ b/src/main/java/net/minecraft/server/WorldNBTStorage.java -@@ -0,0 +0,0 @@ public class WorldNBTStorage implements IDataManager, IPlayerFileData { +@@ -0,0 +0,0 @@ public class WorldNBTStorage implements IPlayerFileData { public WorldNBTStorage(File file, String s, @Nullable MinecraftServer minecraftserver, DataFixer datafixer) { this.a = datafixer; diff --git a/Spigot-Server-Patches/Restore-vanlla-default-mob-spawn-range.patch b/Spigot-Server-Patches/Restore-vanlla-default-mob-spawn-range.patch index 78dfe62055..c108ca28b5 100644 --- a/Spigot-Server-Patches/Restore-vanlla-default-mob-spawn-range.patch +++ b/Spigot-Server-Patches/Restore-vanlla-default-mob-spawn-range.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Restore vanlla default mob-spawn-range diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java -index 1d222eaff7..809ce1d6aa 100644 +index 222adb40c..5a0b9567f 100644 --- a/src/main/java/org/spigotmc/SpigotWorldConfig.java +++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java @@ -0,0 +0,0 @@ public class SpigotWorldConfig diff --git a/Spigot-Server-Patches/Send-nearby-packets-from-world-player-list-not-serve.patch b/Spigot-Server-Patches/Send-nearby-packets-from-world-player-list-not-serve.patch index aabcff83a3..1144c059d6 100644 --- a/Spigot-Server-Patches/Send-nearby-packets-from-world-player-list-not-serve.patch +++ b/Spigot-Server-Patches/Send-nearby-packets-from-world-player-list-not-serve.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Send nearby packets from world player list not server list diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java -index ddaa73e83d..ec760325ba 100644 +index 6d464a3dc..823329268 100644 --- a/src/main/java/net/minecraft/server/PlayerList.java +++ b/src/main/java/net/minecraft/server/PlayerList.java @@ -0,0 +0,0 @@ public abstract class PlayerList { @@ -45,70 +45,21 @@ index ddaa73e83d..ec760325ba 100644 double d4 = d0 - entityplayer.locX; double d5 = d1 - entityplayer.locY; double d6 = d2 - entityplayer.locZ; -diff --git a/src/main/java/net/minecraft/server/WorldManager.java b/src/main/java/net/minecraft/server/WorldManager.java -index b4225b58ec..0ba0eb661b 100644 ---- a/src/main/java/net/minecraft/server/WorldManager.java -+++ b/src/main/java/net/minecraft/server/WorldManager.java -@@ -0,0 +0,0 @@ public class WorldManager implements IWorldAccess { - } - - public void a(@Nullable EntityHuman entityhuman, SoundEffect soundeffect, SoundCategory soundcategory, double d0, double d1, double d2, float f, float f1) { -- // CraftBukkit - this.world.dimension -- this.a.getPlayerList().sendPacketNearby(entityhuman, d0, d1, d2, f > 1.0F ? (double) (16.0F * f) : 16.0D, this.world.dimension, new PacketPlayOutNamedSoundEffect(soundeffect, soundcategory, d0, d1, d2, f, f1)); -+ // CraftBukkit - this.world.dimension, // Paper - this.world.dimension -> this.world -+ this.a.getPlayerList().sendPacketNearby(entityhuman, d0, d1, d2, f > 1.0F ? (double) (16.0F * f) : 16.0D, this.world, new PacketPlayOutNamedSoundEffect(soundeffect, soundcategory, d0, d1, d2, f, f1)); - } - - public void a(int i, int j, int k, int l, int i1, int j1) {} -@@ -0,0 +0,0 @@ public class WorldManager implements IWorldAccess { - - public void a(EntityHuman entityhuman, int i, BlockPosition blockposition, int j) { - // CraftBukkit - this.world.dimension -- this.a.getPlayerList().sendPacketNearby(entityhuman, (double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ(), 64.0D, this.world.dimension, new PacketPlayOutWorldEvent(i, blockposition, j, false)); -+ this.a.getPlayerList().sendPacketNearby(entityhuman, (double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ(), 64.0D, this.world, new PacketPlayOutWorldEvent(i, blockposition, j, false)); - } - - public void a(int i, BlockPosition blockposition, int j) { -@@ -0,0 +0,0 @@ public class WorldManager implements IWorldAccess { - } - - public void b(int i, BlockPosition blockposition, int j) { -- Iterator iterator = this.a.getPlayerList().v().iterator(); -+ // Iterator iterator = this.a.getPlayerList().v().iterator(); // Paper - - // CraftBukkit start - EntityHuman entityhuman = null; -@@ -0,0 +0,0 @@ public class WorldManager implements IWorldAccess { - if (entity instanceof EntityHuman) entityhuman = (EntityHuman) entity; - // CraftBukkit end - -+ // Paper start -+ java.util.List list = entity != null ? entity.world.players : this.a.getPlayerList().v(); -+ Iterator iterator = list.iterator(); - while (iterator.hasNext()) { -- EntityPlayer entityplayer = (EntityPlayer) iterator.next(); -+ EntityHuman human = iterator.next(); -+ if (!(human instanceof EntityPlayer)) continue; -+ EntityPlayer entityplayer = (EntityPlayer) human; -+ // Paper end - - if (entityplayer != null && entityplayer.world == this.world && entityplayer.getId() != i) { - double d0 = (double) blockposition.getX() - entityplayer.locX; diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index 4cda6cee2b..0ff3fe03dd 100644 +index 3bfe40bb6..ffa5a0bee 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java -@@ -0,0 +0,0 @@ public class WorldServer extends World implements IAsyncTaskHandler { +@@ -0,0 +0,0 @@ public class WorldServer extends World { } // CraftBukkit end - if (super.strikeLightning(entity)) { -- this.server.getPlayerList().sendPacketNearby((EntityHuman) null, entity.locX, entity.locY, entity.locZ, 512.0D, dimension, new PacketPlayOutSpawnEntityWeather(entity)); // CraftBukkit - Use dimension -+ this.server.getPlayerList().sendPacketNearby((EntityHuman) null, entity.locX, entity.locY, entity.locZ, 512.0D, this, new PacketPlayOutSpawnEntityWeather(entity)); // CraftBukkit - Use dimension, // Paper - use world instead of dimension - return true; - } else { - return false; -@@ -0,0 +0,0 @@ public class WorldServer extends World implements IAsyncTaskHandler { - BlockActionData blockactiondata = (BlockActionData) this.d.removeFirst(); + this.globalEntityList.add(entitylightning); +- this.server.getPlayerList().sendPacketNearby((EntityHuman) null, entitylightning.locX, entitylightning.locY, entitylightning.locZ, 512.0D, this.worldProvider.getDimensionManager(), new PacketPlayOutSpawnEntityWeather(entitylightning)); ++ this.server.getPlayerList().sendPacketNearby((EntityHuman) null, entitylightning.locX, entitylightning.locY, entitylightning.locZ, 512.0D, this, new PacketPlayOutSpawnEntityWeather(entitylightning)); // Paper - use world instead of dimension + } + + @Override +@@ -0,0 +0,0 @@ public class WorldServer extends World { + BlockActionData blockactiondata = (BlockActionData) this.J.removeFirst(); if (this.a(blockactiondata)) { - // CraftBukkit - this.worldProvider.dimension -> this.dimension @@ -119,7 +70,7 @@ index 4cda6cee2b..0ff3fe03dd 100644 } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 4594bab465..72eb8ed4f4 100644 +index 03148879f..e336813bd 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -0,0 +0,0 @@ public class CraftWorld implements World { diff --git a/Spigot-Server-Patches/Use-ConcurrentHashMap-in-JsonList.patch b/Spigot-Server-Patches/Use-ConcurrentHashMap-in-JsonList.patch index 0b8c36906d..ef5591d249 100644 --- a/Spigot-Server-Patches/Use-ConcurrentHashMap-in-JsonList.patch +++ b/Spigot-Server-Patches/Use-ConcurrentHashMap-in-JsonList.patch @@ -25,11 +25,11 @@ The point of this is readability, but does have a side-benefit of a small microp Finally, added a couple obfhelpers for the modified code diff --git a/src/main/java/net/minecraft/server/JsonList.java b/src/main/java/net/minecraft/server/JsonList.java -index 026ef7939e..b7cde4d418 100644 +index 04f98167d..c169d0176 100644 --- a/src/main/java/net/minecraft/server/JsonList.java +++ b/src/main/java/net/minecraft/server/JsonList.java @@ -0,0 +0,0 @@ public class JsonList> { - protected static final Logger a = LogManager.getLogger(); + protected static final Logger LOGGER = LogManager.getLogger(); protected final Gson b; private final File c; - private final Map d = Maps.newHashMap(); diff --git a/Spigot-Server-Patches/Use-a-Queue-for-Queueing-Commands.patch b/Spigot-Server-Patches/Use-a-Queue-for-Queueing-Commands.patch index 81af6baf51..f20fbdaf3c 100644 --- a/Spigot-Server-Patches/Use-a-Queue-for-Queueing-Commands.patch +++ b/Spigot-Server-Patches/Use-a-Queue-for-Queueing-Commands.patch @@ -6,18 +6,18 @@ Subject: [PATCH] Use a Queue for Queueing Commands Lists are bad as Queues mmmkay. diff --git a/src/main/java/net/minecraft/server/DedicatedServer.java b/src/main/java/net/minecraft/server/DedicatedServer.java -index 437ac386ac..21a05b2b21 100644 +index c2c676e3b..3d452fe0e 100644 --- a/src/main/java/net/minecraft/server/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/DedicatedServer.java @@ -0,0 +0,0 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer private static final Logger LOGGER = LogManager.getLogger(); - private static final Pattern h = Pattern.compile("^[a-fA-F0-9]{40}$"); + private static final Pattern j = Pattern.compile("^[a-fA-F0-9]{40}$"); - private final List serverCommandQueue = Collections.synchronizedList(Lists.newArrayList()); + private final java.util.Queue serverCommandQueue = new java.util.concurrent.ConcurrentLinkedQueue(); // Paper - use a proper queue - private RemoteStatusListener j; - public final RemoteControlCommandListener remoteControlCommandListener = new RemoteControlCommandListener(this); - private RemoteControlListener l; + private RemoteStatusListener l; + public final RemoteControlCommandListener remoteControlCommandListener; + private RemoteControlListener remoteControlListener; @@ -0,0 +0,0 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer public void handleCommandQueue() { diff --git a/Spigot-Server-Patches/World-EntityHuman-Lookup-Optimizations.patch b/Spigot-Server-Patches/World-EntityHuman-Lookup-Optimizations.patch deleted file mode 100644 index 512474eac7..0000000000 --- a/Spigot-Server-Patches/World-EntityHuman-Lookup-Optimizations.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: willies952002 -Date: Mon, 30 Jul 2018 02:42:49 -0400 -Subject: [PATCH] World EntityHuman Lookup Optimizations - - -diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index 5d60b36678..3acea908c2 100644 ---- a/src/main/java/net/minecraft/server/World.java -+++ b/src/main/java/net/minecraft/server/World.java -@@ -0,0 +0,0 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc - private final List c = Lists.newArrayList(); - private final Set tileEntityListUnload = com.google.common.collect.Sets.newHashSet(); // Paper - public final List players = Lists.newArrayList(); -+ public final Map playersByName = Maps.newHashMap(); // Paper - World EntityHuman Lookup Optimizations - public final List k = Lists.newArrayList(); - protected final IntHashMap entitiesById = new IntHashMap<>(); - private final long F = 16777215L; -@@ -0,0 +0,0 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc - EntityHuman entityhuman = (EntityHuman) entity; - - this.players.add(entityhuman); -+ this.playersByName.put(entityhuman.getName(), entityhuman); -+ // Paper end - this.everyoneSleeping(); - } - -@@ -0,0 +0,0 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc - entity.die(); - if (entity instanceof EntityHuman) { - this.players.remove(entity); -+ this.playersByName.remove(entity.getName()); // Paper - World EntityHuman Lookup Optimizations - // Spigot start - for ( WorldPersistentData worldData : worldMaps.worldMap.values() ) - { -@@ -0,0 +0,0 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc - entity.die(); - if (entity instanceof EntityHuman) { - this.players.remove(entity); -+ this.playersByName.remove(entity.getName()); // Paper - World EntityHuman Lookup Optimizations - this.everyoneSleeping(); - } - -@@ -0,0 +0,0 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc - - @Nullable - public EntityHuman a(String s) { -+ // Paper start - World EntityHuman Lookup Optimizations -+ /* - for (int i = 0; i < this.players.size(); ++i) { - EntityHuman entityhuman = (EntityHuman) this.players.get(i); - -@@ -0,0 +0,0 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc - } - - return null; -+ */ -+ return this.playersByName.get(s); -+ // Paper end - } - - @Nullable - public EntityHuman b(UUID uuid) { -+ // Paper start - World EntityHuman Lookup Optimizations -+ /* - for (int i = 0; i < this.players.size(); ++i) { - EntityHuman entityhuman = (EntityHuman) this.players.get(i); - -@@ -0,0 +0,0 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc - } - - return null; -+ */ -+ Entity entity = ((WorldServer)this).entitiesByUUID.get(uuid); -+ return entity instanceof EntityHuman ? (EntityHuman) entity : null; -+ // Paper end - } - - public void checkSession() throws ExceptionWorldConflict { --- \ No newline at end of file