diff --git a/Spigot-Server-Patches/0233-Fix-MC-117075-TE-Unload-Lag-Spike.patch b/Spigot-Server-Patches/0233-Fix-MC-117075-TE-Unload-Lag-Spike.patch index 15d1ed631..10b680bb1 100644 --- a/Spigot-Server-Patches/0233-Fix-MC-117075-TE-Unload-Lag-Spike.patch +++ b/Spigot-Server-Patches/0233-Fix-MC-117075-TE-Unload-Lag-Spike.patch @@ -1,32 +1,9 @@ -From f2bcb786e5eed44c74b3ebc8573f5735e589cd6d Mon Sep 17 00:00:00 2001 +From ed74bb4fedd0ddfc6385eb36ae705420be3b6c50 Mon Sep 17 00:00:00 2001 From: mezz Date: Wed, 9 Aug 2017 17:51:22 -0500 Subject: [PATCH] Fix MC-117075: TE Unload Lag Spike -diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java -index ed595955..228792fa 100644 ---- a/src/main/java/net/minecraft/server/Chunk.java -+++ b/src/main/java/net/minecraft/server/Chunk.java -@@ -823,6 +823,9 @@ public class Chunk { - - public void removeEntities() { - this.j = false; -+ // Paper start - Fix MC-117075: TE Unload Lag Spike -+ this.world.markTileEntitiesForRemoval(this); -+ /* - Iterator iterator = this.tileEntities.values().iterator(); - - while (iterator.hasNext()) { -@@ -842,6 +845,8 @@ public class Chunk { - - this.world.b(tileentity); - } -+ */ -+ // Paper end - - List[] aentityslice = this.entitySlices; // Spigot - int i = aentityslice.length; diff --git a/src/main/java/net/minecraft/server/ChunkCoordIntPair.java b/src/main/java/net/minecraft/server/ChunkCoordIntPair.java index 23944088..e8d1a1c6 100644 --- a/src/main/java/net/minecraft/server/ChunkCoordIntPair.java @@ -40,66 +17,22 @@ index 23944088..e8d1a1c6 100644 return (long) i & 4294967295L | ((long) j & 4294967295L) << 32; } diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index 12938b9f..e4fd7fa7 100644 +index 12938b9f..4585f2ef 100644 --- a/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java -@@ -147,6 +147,7 @@ public abstract class World implements IBlockAccess { - private org.spigotmc.TickLimiter tileLimiter; - private int tileTickPosition; - public final Map explosionDensityCache = new HashMap<>(); // Paper - Optimize explosions -+ private it.unimi.dsi.fastutil.longs.LongCollection tileEntitiesChunkToBeRemoved = new it.unimi.dsi.fastutil.longs.LongOpenHashSet(); // Paper - Fix MC-117075: TE Unload Lag Spike - - public CraftWorld getWorld() { - return this.world; -@@ -1581,6 +1582,7 @@ public abstract class World implements IBlockAccess { +@@ -1576,7 +1576,11 @@ public abstract class World implements IBlockAccess { + timings.tileEntityTick.startTiming(); // Spigot + // CraftBukkit start - From below, clean up tile entities before ticking them + if (!this.tileEntityListUnload.isEmpty()) { +- this.tileEntityListTick.removeAll(this.tileEntityListUnload); ++ // Paper start - Use alternate implementation with faster contains ++ java.util.Set toRemove = java.util.Collections.newSetFromMap(new java.util.IdentityHashMap<>()); ++ toRemove.addAll(tileEntityListUnload); ++ this.tileEntityListTick.removeAll(toRemove); ++ // Paper end + //this.tileEntityList.removeAll(this.tileEntityListUnload); // Paper - remove unused list this.tileEntityListUnload.clear(); } - // CraftBukkit end -+ this.removeTileEntitiesForRemovedChunks(); // Paper - Fix MC-117075: TE Unload Lag Spike - - // Spigot start - // Iterator iterator = this.tileEntityListTick.iterator(); -@@ -3261,4 +3263,40 @@ public abstract class World implements IBlockAccess { - public BlockPosition a(String s, BlockPosition blockposition, boolean flag) { - return null; - } -+ -+ // Paper start - Fix MC-117075: TE Unload Lag Spike -+ public void markTileEntitiesForRemoval(Chunk chunk) { -+ if (!chunk.getTileEntities().isEmpty()) { -+ long pos = net.minecraft.server.ChunkCoordIntPair.asLong(chunk.locX, chunk.locZ); -+ this.tileEntitiesChunkToBeRemoved.add(pos); -+ } -+ } -+ -+ private void removeTileEntitiesForRemovedChunks() { -+ if (!this.tileEntitiesChunkToBeRemoved.isEmpty()) { -+ java.util.function.Predicate isInChunkOrNull = (tileEntity) -> { -+ if (tileEntity == null) { -+ return true; -+ } -+ -+ BlockPosition tilePos = tileEntity.getPosition(); -+ long tileChunkPos = net.minecraft.server.ChunkCoordIntPair.asLong(tilePos.getX() >> 4, tilePos.getZ() >> 4); -+ final boolean willRemove = this.tileEntitiesChunkToBeRemoved.contains(tileChunkPos); -+ // Brought over from Chunk#removeEntities -+ if (willRemove && tileEntity instanceof IInventory) { -+ for (org.bukkit.entity.HumanEntity human : Lists.newArrayList(((IInventory) tileEntity).getViewers())) { -+ if (human instanceof org.bukkit.craftbukkit.entity.CraftHumanEntity) { -+ ((org.bukkit.craftbukkit.entity.CraftHumanEntity) human).getHandle().closeInventory(); -+ } -+ } -+ } -+ -+ return willRemove; -+ }; -+ -+ this.tileEntityListTick.removeIf(isInChunkOrNull); -+ this.tileEntitiesChunkToBeRemoved.clear(); -+ } -+ } -+ // Paper end - } -- -2.14.1 +2.14.1.windows.1