From 52cf890602e69c8292f9c895ffb1d382991a8e8c Mon Sep 17 00:00:00 2001 From: Aikar Date: Thu, 2 Apr 2020 00:42:15 -0400 Subject: [PATCH] Remove some old removed 1.14 patches that are never going to be needed (fixed/already applied) --- ...entation-of-tile-entity-removal-list.patch | 56 --- ...atch-Async-PlayerChunkMap-operations.patch | 26 -- .../0077-Don-t-teleport-dead-entities.patch | 24 -- ...-Optimize-and-Fix-ExpiringMap-Issues.patch | 336 ------------------ ...h-entity-loss-due-to-unloaded-chunks.patch | 44 --- 5 files changed, 486 deletions(-) delete mode 100644 removed/1.14/0052-Change-implementation-of-tile-entity-removal-list.patch delete mode 100644 removed/1.14/0074-Catch-Async-PlayerChunkMap-operations.patch delete mode 100644 removed/1.14/0077-Don-t-teleport-dead-entities.patch delete mode 100644 removed/1.14/0353-Optimize-and-Fix-ExpiringMap-Issues.patch delete mode 100644 removed/1.14/0364-Fix-issues-with-entity-loss-due-to-unloaded-chunks.patch diff --git a/removed/1.14/0052-Change-implementation-of-tile-entity-removal-list.patch b/removed/1.14/0052-Change-implementation-of-tile-entity-removal-list.patch deleted file mode 100644 index 7fa854325..000000000 --- a/removed/1.14/0052-Change-implementation-of-tile-entity-removal-list.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 67da8daf252ff15052efa583fc83015bf3756291 Mon Sep 17 00:00:00 2001 -From: Joseph Hirschfeld -Date: Thu, 3 Mar 2016 02:39:54 -0600 -Subject: [PATCH] Change implementation of (tile)entity removal list - -use sets for faster removal - -diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index a80acbb6a5..09cf98ccdd 100644 ---- a/src/main/java/net/minecraft/server/World.java -+++ b/src/main/java/net/minecraft/server/World.java -@@ -68,11 +68,11 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc - } - }; - // Spigot end -- protected final List g = Lists.newArrayList(); -+ protected final Set g = com.google.common.collect.Sets.newHashSet(); // Paper - public final List tileEntityList = Lists.newArrayList(); - public final List tileEntityListTick = Lists.newArrayList(); - private final List c = Lists.newArrayList(); -- private final List tileEntityListUnload = Lists.newArrayList(); -+ private final Set tileEntityListUnload = com.google.common.collect.Sets.newHashSet(); // Paper - public final List players = Lists.newArrayList(); - public final List k = Lists.newArrayList(); - protected final IntHashMap entitiesById = new IntHashMap<>(); -@@ -1095,20 +1095,21 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc - this.entityList.removeAll(this.g); - - int j; -- -- for (i = 0; i < this.g.size(); ++i) { -- entity = (Entity) this.g.get(i); -+ // Paper start - Set based removal lists -+ for (Iterator it = this.g.iterator(); it.hasNext() ; ) { -+ entity = it.next(); // Paper - int k = entity.chunkX; - - j = entity.chunkZ; - if (entity.inChunk && this.isChunkLoaded(k, j, true)) { - this.getChunkAt(k, j).b(entity); - } -- } -+ //} // Paper - merge - -- for (i = 0; i < this.g.size(); ++i) { -- this.c((Entity) this.g.get(i)); -+ //for (Entity e : this.g) { // Paper - merge -+ this.c(entity); // Paper use entity - } -+ // Paper end - - this.g.clear(); - this.p_(); --- -2.21.0 - diff --git a/removed/1.14/0074-Catch-Async-PlayerChunkMap-operations.patch b/removed/1.14/0074-Catch-Async-PlayerChunkMap-operations.patch deleted file mode 100644 index 62247d4fb..000000000 --- a/removed/1.14/0074-Catch-Async-PlayerChunkMap-operations.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 513795a62119bbb58aa92ca9d1028cc8c07b4850 Mon Sep 17 00:00:00 2001 -From: Daniel Ennis -Date: Sun, 20 Mar 2016 15:22:42 -0400 -Subject: [PATCH] Catch Async PlayerChunkMap operations - - -diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java -index 55161af9c9..2064576501 100644 ---- a/src/main/java/net/minecraft/server/PlayerChunkMap.java -+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java -@@ -434,10 +434,12 @@ public class PlayerChunkMap { - } - - public void a(PlayerChunk playerchunk) { -+ org.spigotmc.AsyncCatcher.catchOp("Async Player Chunk Add"); // Paper - this.f.add(playerchunk); - } - - public void b(PlayerChunk playerchunk) { -+ org.spigotmc.AsyncCatcher.catchOp("Async Player Chunk Remove"); // Paper - ChunkCoordIntPair chunkcoordintpair = playerchunk.a(); - long i = d(chunkcoordintpair.x, chunkcoordintpair.z); - --- -2.21.0 - diff --git a/removed/1.14/0077-Don-t-teleport-dead-entities.patch b/removed/1.14/0077-Don-t-teleport-dead-entities.patch deleted file mode 100644 index 3fd381482..000000000 --- a/removed/1.14/0077-Don-t-teleport-dead-entities.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 232f2c9e71828f540e69196dee974ef5f5e2ba07 Mon Sep 17 00:00:00 2001 -From: Aikar -Date: Tue, 22 Mar 2016 00:55:23 -0400 -Subject: [PATCH] Don't teleport dead entities - -Had some issue with this in past, and this is the vanilla logic. -Potentially an old CB change that's no longer needed. - -diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java -index cbbb243d1c..dba97f2305 100644 ---- a/src/main/java/net/minecraft/server/Entity.java -+++ b/src/main/java/net/minecraft/server/Entity.java -@@ -2579,7 +2579,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke - } - - public Entity teleportTo(Location exit, boolean portal) { -- if (true) { -+ if (!this.dead) { // Paper - WorldServer worldserver = ((CraftWorld) getBukkitEntity().getLocation().getWorld()).getHandle(); - WorldServer worldserver1 = ((CraftWorld) exit.getWorld()).getHandle(); - DimensionManager dimensionmanager = worldserver1.dimension; --- -2.21.0 - diff --git a/removed/1.14/0353-Optimize-and-Fix-ExpiringMap-Issues.patch b/removed/1.14/0353-Optimize-and-Fix-ExpiringMap-Issues.patch deleted file mode 100644 index 37366c73e..000000000 --- a/removed/1.14/0353-Optimize-and-Fix-ExpiringMap-Issues.patch +++ /dev/null @@ -1,336 +0,0 @@ -From c6ea2b8e4435461e2bfd287410e4a0845eb47720 Mon Sep 17 00:00:00 2001 -From: Aikar -Date: Sun, 16 Sep 2018 00:00:16 -0400 -Subject: [PATCH] Optimize and Fix ExpiringMap Issues - -computeIfAbsent would leak as the entry was never -registered into the ttl map, as well as some other -methods were at risk, so they were added. - -This also synchronizes all access make the map thread safe. - -This also redesigns cleaning to not run on every -manipulation, and instead to run clean -once per tick per active expiring map. - -diff --git a/src/main/java/net/minecraft/server/ChunkGeneratorAbstract.java b/src/main/java/net/minecraft/server/ChunkGeneratorAbstract.java -index a237684410..835a2aae40 100644 ---- a/src/main/java/net/minecraft/server/ChunkGeneratorAbstract.java -+++ b/src/main/java/net/minecraft/server/ChunkGeneratorAbstract.java -@@ -142,13 +142,13 @@ public abstract class ChunkGeneratorAbstract implem - - public Long2ObjectMap getStructureStartCache(StructureGenerator structuregenerator) { - return (Long2ObjectMap) this.d.computeIfAbsent(structuregenerator, (structuregenerator1) -> { -- return Long2ObjectMaps.synchronize(new ExpiringMap<>(8192, 10000)); -+ return new ExpiringMap<>(8192, 10000); // Paper - already synchronized - }); - } - - public Long2ObjectMap getStructureCache(StructureGenerator structuregenerator) { - return (Long2ObjectMap) this.e.computeIfAbsent(structuregenerator, (structuregenerator1) -> { -- return Long2ObjectMaps.synchronize(new ExpiringMap<>(8192, 10000)); -+ return new ExpiringMap<>(8192, 10000); // Paper - already synchronized - }); - } - -diff --git a/src/main/java/net/minecraft/server/ExpiringMap.java b/src/main/java/net/minecraft/server/ExpiringMap.java -index bd36364796..bf6095137a 100644 ---- a/src/main/java/net/minecraft/server/ExpiringMap.java -+++ b/src/main/java/net/minecraft/server/ExpiringMap.java -@@ -2,87 +2,211 @@ package net.minecraft.server; - - import it.unimi.dsi.fastutil.longs.Long2LongLinkedOpenHashMap; - import it.unimi.dsi.fastutil.longs.Long2LongMap; -+import it.unimi.dsi.fastutil.longs.Long2ObjectMaps; - import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; --import it.unimi.dsi.fastutil.longs.Long2LongMap.Entry; - import it.unimi.dsi.fastutil.objects.ObjectCollection; - import it.unimi.dsi.fastutil.objects.ObjectIterator; - import java.util.Map; -+import java.util.function.BiFunction; -+import java.util.function.Function; - import java.util.function.LongFunction; - --public class ExpiringMap extends Long2ObjectOpenHashMap { -- -+public class ExpiringMap extends Long2ObjectMaps.SynchronizedMap { // paper - synchronize accesss - private final int a; -- private final Long2LongMap b = new Long2LongLinkedOpenHashMap(); -+ private final Long2LongMap ttl = new Long2LongLinkedOpenHashMap(); // Paper -+ private static final boolean DEBUG_EXPIRING_MAP = Boolean.getBoolean("debug.expiringmap"); - - public ExpiringMap(int i, int j) { -- super(i); -+ super(new Long2ObjectOpenHashMap<>(i)); // Paper - this.a = j; - } - -+ // Paper start -+ private void setAccess(long i) { a(i); } // Paper - OBFHELPER - private void a(long i) { -- long j = SystemUtils.getMonotonicMillis(); -+ synchronized (this.sync) { -+ long j = System.currentTimeMillis(); // Paper -+ this.ttl.put(i, j); -+ if (!registered) { -+ registered = true; -+ MinecraftServer.getServer().expiringMaps.add(this); -+ } -+ } -+ } - -- this.b.put(i, j); -- // CraftBukkit start -- cleanup(); -+ @Override -+ public T compute(long l, BiFunction biFunction) { -+ setAccess(l); -+ return super.compute(l, biFunction); - } - -- public void cleanup() { -- long j = SystemUtils.getMonotonicMillis(); -- // CraftBukkit end -- ObjectIterator objectiterator = this.b.long2LongEntrySet().iterator(); -+ @Override -+ public T putIfAbsent(long l, T t) { -+ setAccess(l); -+ return super.putIfAbsent(l, t); -+ } - -- while (objectiterator.hasNext()) { -- Long2LongMap.Entry entry = (Long2LongMap.Entry) objectiterator.next(); // CraftBukkit - decompile error -- T t0 = super.get(entry.getLongKey()); -+ @Override -+ public T computeIfPresent(long l, BiFunction biFunction) { -+ setAccess(l); -+ return super.computeIfPresent(l, biFunction); -+ } - -- if (j - entry.getLongValue() <= (long) this.a) { -- break; -- } -+ @Override -+ public T computeIfAbsent(long l, LongFunction longFunction) { -+ setAccess(l); -+ return super.computeIfAbsent(l, longFunction); -+ } - -- if (t0 != null && this.a(t0)) { -- super.remove(entry.getLongKey()); -- objectiterator.remove(); -- } -+ -+ @Override -+ public boolean replace(long l, T t, T v1) { -+ setAccess(l); -+ return super.replace(l, t, v1); -+ } -+ -+ @Override -+ public T replace(long l, T t) { -+ setAccess(l); -+ return super.replace(l, t); -+ } -+ -+ @Override -+ public T putIfAbsent(Long aLong, T t) { -+ setAccess(aLong); -+ return super.putIfAbsent(aLong, t); -+ } -+ -+ @Override -+ public boolean replace(Long aLong, T t, T v1) { -+ setAccess(aLong); -+ return super.replace(aLong, t, v1); -+ } -+ -+ @Override -+ public T replace(Long aLong, T t) { -+ setAccess(aLong); -+ return super.replace(aLong, t); -+ } -+ -+ @Override -+ public T computeIfAbsent(Long aLong, Function function) { -+ setAccess(aLong); -+ return super.computeIfAbsent(aLong, function); -+ } -+ -+ @Override -+ public T computeIfPresent(Long aLong, BiFunction biFunction) { -+ setAccess(aLong); -+ return super.computeIfPresent(aLong, biFunction); -+ } -+ -+ @Override -+ public T compute(Long aLong, BiFunction biFunction) { -+ setAccess(aLong); -+ return super.compute(aLong, biFunction); -+ } -+ -+ @Override -+ public void clear() { -+ synchronized (this.sync) { -+ ttl.clear(); -+ super.clear(); - } -+ } - -+ private boolean registered = false; -+ -+ // Break clean to its own method to be ticked -+ boolean clean() { -+ synchronized (this.sync) { -+ long now = System.currentTimeMillis(); -+ ObjectIterator objectiterator = this.ttl.long2LongEntrySet().iterator(); // Paper -+ -+ while (objectiterator.hasNext()) { -+ Long2LongMap.Entry entry = objectiterator.next(); // Paper -+ T object = super.get(entry.getLongKey()); // Paper -+ if (now - entry.getLongValue() <= (long) this.a) { -+ break; -+ } -+ -+ if (object != null && this.a(object)) { -+ super.remove(entry.getLongKey()); -+ objectiterator.remove(); -+ } -+ } -+ int ttlSize = this.ttl.size(); -+ int thisSize = this.size(); -+ if (ttlSize < thisSize) { -+ if (DEBUG_EXPIRING_MAP) { -+ MinecraftServer.LOGGER.warn("WARNING: ExpiringMap desync (ttl:" + ttlSize + " < actual:" + thisSize + ")"); -+ } -+ try { -+ for (Entry entry : this.long2ObjectEntrySet()) { -+ ttl.putIfAbsent(entry.getLongKey(), now); -+ } -+ } catch (Exception ignored) { -+ } // Ignore any como's -+ } else if (ttlSize > this.size()) { -+ if (DEBUG_EXPIRING_MAP) { -+ MinecraftServer.LOGGER.warn("WARNING: ExpiringMap desync (ttl:" + ttlSize + " > actual:" + thisSize + ")"); -+ } -+ try { -+ this.ttl.long2LongEntrySet().removeIf(entry -> !this.containsKey(entry.getLongKey())); -+ } catch (Exception ignored) { -+ } // Ignore any como's -+ } -+ if (isEmpty()) { -+ registered = false; -+ return true; -+ } -+ return false; -+ } -+ // Paper end - } - -- protected boolean a(T t0) { -+ protected boolean a(T var1) { - return true; - } - -- public T put(long i, T t0) { -+ public T put(long i, T object) { - this.a(i); -- return super.put(i, t0); -+ return (T)super.put(i, object); - } - -- public T put(Long olong, T t0) { -+ public T put(Long olong, T object) { - this.a(olong); -- return super.put(olong, t0); -+ return (T)super.put(olong, object); - } - - public T get(long i) { -- this.a(i); -- return super.get(i); -+ // Paper start - don't setAccess unless a hit -+ T t = super.get(i); -+ if (t != null) { -+ this.setAccess(i); -+ } -+ return t; -+ // Paper end - } - -- public void putAll(Map map) { -+ public void putAll(Map var1) { - throw new RuntimeException("Not implemented"); - } - -- public T remove(long i) { -+ public T remove(long var1) { - throw new RuntimeException("Not implemented"); - } - -- public T remove(Object object) { -+ public T remove(Object var1) { - throw new RuntimeException("Not implemented"); - } - -+ // Paper start -+ /* - // CraftBukkit start - @Override - public T computeIfAbsent(long l, LongFunction lf) { -- this.b.put(l, SystemUtils.getMonotonicMillis()); -+ this.ttl.put(l, SystemUtils.getMonotonicMillis()); // Paper - return super.computeIfAbsent(l, lf); - } - -@@ -92,4 +216,5 @@ public class ExpiringMap extends Long2ObjectOpenHashMap { - return super.values(); - } - // CraftBukkit end -+ */ // Paper end - } -diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 38c0201acb..ae271a57fc 100644 ---- a/src/main/java/net/minecraft/server/MinecraftServer.java -+++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -150,6 +150,7 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati - public int autosavePeriod; - public File bukkitDataPackFolder; - public CommandDispatcher vanillaCommandDispatcher; -+ public List expiringMaps = java.util.Collections.synchronizedList(new java.util.ArrayList<>()); // Paper - // CraftBukkit end - // Spigot start - public static final int TPS = 20; -@@ -995,6 +996,7 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati - this.methodProfiler.exit(); - org.spigotmc.WatchdogThread.tick(); // Spigot - PaperLightingQueue.processQueue(startTime); // Paper -+ expiringMaps.removeIf(ExpiringMap::clean); // Paper - this.slackActivityAccountant.tickEnded(l); // Spigot - co.aikar.timings.TimingsManager.FULL_SERVER_TICK.stopTiming(); // Paper - } -diff --git a/src/main/java/org/bukkit/craftbukkit/generator/CustomChunkGenerator.java b/src/main/java/org/bukkit/craftbukkit/generator/CustomChunkGenerator.java -index 23f4e24cea..9e553866eb 100644 ---- a/src/main/java/org/bukkit/craftbukkit/generator/CustomChunkGenerator.java -+++ b/src/main/java/org/bukkit/craftbukkit/generator/CustomChunkGenerator.java -@@ -159,7 +159,7 @@ public class CustomChunkGenerator extends InternalChunkGenerator getStructureStartCache(StructureGenerator structuregenerator) { - return (Long2ObjectMap) this.structureStartCache.computeIfAbsent(structuregenerator, (s) -> { -- return Long2ObjectMaps.synchronize(new ExpiringMap(8192, 10000)); -+ return new ExpiringMap(8192, 10000); // Paper - already synchronized - }); - } - -@@ -169,7 +169,7 @@ public class CustomChunkGenerator extends InternalChunkGenerator getStructureCache(StructureGenerator structuregenerator) { - return (Long2ObjectMap) this.structureCache.computeIfAbsent(structuregenerator, (s) -> { -- return Long2ObjectMaps.synchronize(new ExpiringMap(8192, 10000)); -+ return new ExpiringMap(8192, 10000); // Paper - already synchronized - }); - } - --- -2.21.0 - diff --git a/removed/1.14/0364-Fix-issues-with-entity-loss-due-to-unloaded-chunks.patch b/removed/1.14/0364-Fix-issues-with-entity-loss-due-to-unloaded-chunks.patch deleted file mode 100644 index 7c76dcc94..000000000 --- a/removed/1.14/0364-Fix-issues-with-entity-loss-due-to-unloaded-chunks.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 54fce61ce9cd7da50f7fa8d635f7364ee724b6d8 Mon Sep 17 00:00:00 2001 -From: Aikar -Date: Fri, 28 Sep 2018 21:49:53 -0400 -Subject: [PATCH] Fix issues with entity loss due to unloaded chunks - -Vanilla has risk of losing entities by causing them to be -removed from all chunks if they try to move into an unloaded chunk. - -This pretty much means high chance this entity will be lost in this scenario. - -There is another case that adding an entity to the world can fail if -the chunk isn't loaded. - -Lots of the server is designed around addEntity never expecting to fail for these reasons, -nor is it really logical. - -This change ensures the chunks are always loaded when entities are -added to the world, or a valid entity moves between chunks. - -diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index fb71879ac0..728319968b 100644 ---- a/src/main/java/net/minecraft/server/World.java -+++ b/src/main/java/net/minecraft/server/World.java -@@ -1081,7 +1081,7 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc - - int i = MathHelper.floor(entity.locX / 16.0D); - int j = MathHelper.floor(entity.locZ / 16.0D); -- boolean flag = entity.attachedToPlayer; -+ boolean flag = true; // Paper - always load chunks for entity adds - - // Paper start - Set origin location when the entity is being added to the world - if (entity.origin == null) { -@@ -1577,7 +1577,7 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc - this.getChunkAt(entity.chunkX, entity.chunkZ).a(entity, entity.chunkY); - } - -- if (!entity.bN() && !this.isChunkLoaded(i, k, true)) { -+ if (!entity.valid && !entity.bN() && !this.isChunkLoaded(i, k, true)) { // Paper - always load chunks to register valid entities location - entity.inChunk = false; - } else { - this.getChunkAt(i, k).a(entity); --- -2.21.0 -