From a054aa6f0251ea820b85ac53a44fe3c64fb325cc Mon Sep 17 00:00:00 2001 From: Aikar Date: Sun, 10 May 2020 05:52:31 -0400 Subject: [PATCH] Properly remove Entities from current chunk We store a reference to the chunk the entity is currently in, so use it to more accurately unregister it in chunkCheck Should maybe fix some entity loss issues. --- ...ith-entity-loss-due-to-unloaded-chunks.patch | 17 +++++++++++++---- .../0370-Duplicate-UUID-Resolve-Option.patch | 4 ++-- ...able-Keep-Spawn-Loaded-range-per-world.patch | 4 ++-- .../0378-incremental-chunk-saving.patch | 6 +++--- ...ural-Spawned-mobs-towards-natural-spaw.patch | 4 ++-- ...as-being-ticked-when-notifying-navigat.patch | 6 +++--- ...0390-Asynchronous-chunk-IO-and-loading.patch | 4 ++-- ...k-if-we-have-a-custom-Bukkit-generator.patch | 6 +++--- ...plement-optional-per-player-mob-spawns.patch | 6 +++--- ...sure-Entity-is-never-double-registered.patch | 8 ++++---- ...stering-entities-from-unloading-chunks.patch | 4 ++-- ...le-PlayerChunkMap-adds-crashing-server.patch | 6 +++--- 12 files changed, 42 insertions(+), 33 deletions(-) diff --git a/Spigot-Server-Patches/0369-Fix-issues-with-entity-loss-due-to-unloaded-chunks.patch b/Spigot-Server-Patches/0369-Fix-issues-with-entity-loss-due-to-unloaded-chunks.patch index d8cbfedc27..62e1cc56f7 100644 --- a/Spigot-Server-Patches/0369-Fix-issues-with-entity-loss-due-to-unloaded-chunks.patch +++ b/Spigot-Server-Patches/0369-Fix-issues-with-entity-loss-due-to-unloaded-chunks.patch @@ -19,19 +19,28 @@ 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/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index 955003d5f830b3a6988bf1b3b4058c28d5d48f77..6da2392915eb197a6e4193470f2d9a31981f1f98 100644 +index 955003d5f830b3a6988bf1b3b4058c28d5d48f77..b8b83554e2a7d7d0119ecf479d8e0bef556f775f 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java -@@ -707,7 +707,7 @@ public class WorldServer extends World { - this.getChunkAt(entity.chunkX, entity.chunkZ).a(entity, entity.chunkY); +@@ -703,11 +703,14 @@ public class WorldServer extends World { + int k = MathHelper.floor(entity.locZ() / 16.0D); + + if (!entity.inChunk || entity.chunkX != i || entity.chunkY != j || entity.chunkZ != k) { +- if (entity.inChunk && this.isChunkLoaded(entity.chunkX, entity.chunkZ)) { +- this.getChunkAt(entity.chunkX, entity.chunkZ).a(entity, entity.chunkY); ++ // Paper start - remove entity if its in a chunk more correctly. ++ Chunk currentChunk = entity.getCurrentChunk(); ++ if (currentChunk != null) { ++ currentChunk.removeEntity(entity); } ++ // Paper end - if (!entity.cc() && !this.isChunkLoaded(i, k)) { + if (!entity.valid && !entity.cc() && !this.isChunkLoaded(i, k)) { // Paper - always load chunks to register valid entities location entity.inChunk = false; } else { this.getChunkAt(i, k).a(entity); -@@ -1032,7 +1032,7 @@ public class WorldServer extends World { +@@ -1032,7 +1035,7 @@ public class WorldServer extends World { return false; } // CraftBukkit end diff --git a/Spigot-Server-Patches/0370-Duplicate-UUID-Resolve-Option.patch b/Spigot-Server-Patches/0370-Duplicate-UUID-Resolve-Option.patch index 91f627465e..a0c5ed6e54 100644 --- a/Spigot-Server-Patches/0370-Duplicate-UUID-Resolve-Option.patch +++ b/Spigot-Server-Patches/0370-Duplicate-UUID-Resolve-Option.patch @@ -197,7 +197,7 @@ index 4ee26ff08f7a058648ab54f0dcd81b466a9aced1..1d255ce3833a0ea735bedbb33ae82597 ChunkCoordIntPair chunkcoordintpair = playerchunk.i(); CompletableFuture, PlayerChunk.Failure>> completablefuture = this.a(chunkcoordintpair, 1, (i) -> { diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index 6da2392915eb197a6e4193470f2d9a31981f1f98..081df240f3066008e7aebee92c6b78487ecda377 100644 +index b8b83554e2a7d7d0119ecf479d8e0bef556f775f..f10cb6378b1d9d2e7e28b5897a7098f9441b4f8a 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java @@ -3,6 +3,8 @@ package net.minecraft.server; @@ -209,7 +209,7 @@ index 6da2392915eb197a6e4193470f2d9a31981f1f98..081df240f3066008e7aebee92c6b7848 import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Queues; -@@ -1059,8 +1061,24 @@ public class WorldServer extends World { +@@ -1062,8 +1064,24 @@ public class WorldServer extends World { if (entity1 == null) { return false; } else { diff --git a/Spigot-Server-Patches/0372-Configurable-Keep-Spawn-Loaded-range-per-world.patch b/Spigot-Server-Patches/0372-Configurable-Keep-Spawn-Loaded-range-per-world.patch index 19263a5bfb..63ae21c8fd 100644 --- a/Spigot-Server-Patches/0372-Configurable-Keep-Spawn-Loaded-range-per-world.patch +++ b/Spigot-Server-Patches/0372-Configurable-Keep-Spawn-Loaded-range-per-world.patch @@ -102,10 +102,10 @@ index 3868572aed50c8bffd93727a139a3fbb8dc19688..ae77805f71c6c574d92f39c51b1e48f2 @Override public void a(ChunkCoordIntPair chunkcoordintpair) { diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index 081df240f3066008e7aebee92c6b78487ecda377..ce506e0e1293343ce5f9b6fbb71ef593abaf515b 100644 +index f10cb6378b1d9d2e7e28b5897a7098f9441b4f8a..b28868766117f0cfdcc5db271b9415d9ae97ad19 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java -@@ -1596,13 +1596,89 @@ public class WorldServer extends World { +@@ -1599,13 +1599,89 @@ public class WorldServer extends World { return ((PersistentIdCounts) this.getMinecraftServer().getWorldServer(DimensionManager.OVERWORLD).getWorldPersistentData().a(PersistentIdCounts::new, "idcounts")).a(); } diff --git a/Spigot-Server-Patches/0378-incremental-chunk-saving.patch b/Spigot-Server-Patches/0378-incremental-chunk-saving.patch index 136d25fbb7..6dc53a9e7c 100644 --- a/Spigot-Server-Patches/0378-incremental-chunk-saving.patch +++ b/Spigot-Server-Patches/0378-incremental-chunk-saving.patch @@ -261,10 +261,10 @@ index 34f470779fa5d1cf9638431253024481236c073b..4f5b516144829a7ae11f21a56789ac7a return PlayerChunk.getChunkState(playerchunk.getTicketLevel()); }); diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index ce506e0e1293343ce5f9b6fbb71ef593abaf515b..ad5e538b2498ed0e6d0cb79a6d5055732cddbc14 100644 +index b28868766117f0cfdcc5db271b9415d9ae97ad19..46ad4612a1bd5ab005450645f69b0cb9f6f18aa7 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java -@@ -814,11 +814,44 @@ public class WorldServer extends World { +@@ -817,11 +817,44 @@ public class WorldServer extends World { return this.worldProvider.c(); } @@ -310,7 +310,7 @@ index ce506e0e1293343ce5f9b6fbb71ef593abaf515b..ad5e538b2498ed0e6d0cb79a6d505573 try (co.aikar.timings.Timing ignored = timings.worldSave.startTiming()) { // Paper if (iprogressupdate != null) { iprogressupdate.a(new ChatMessage("menu.savingLevel", new Object[0])); -@@ -845,6 +878,7 @@ public class WorldServer extends World { +@@ -848,6 +881,7 @@ public class WorldServer extends World { // CraftBukkit end } diff --git a/Spigot-Server-Patches/0385-Only-count-Natural-Spawned-mobs-towards-natural-spaw.patch b/Spigot-Server-Patches/0385-Only-count-Natural-Spawned-mobs-towards-natural-spaw.patch index 1a776c40b6..9cb05db1b0 100644 --- a/Spigot-Server-Patches/0385-Only-count-Natural-Spawned-mobs-towards-natural-spaw.patch +++ b/Spigot-Server-Patches/0385-Only-count-Natural-Spawned-mobs-towards-natural-spaw.patch @@ -38,10 +38,10 @@ index ca2ac17747d4f2acf1df056759c5c182be050125..a3fc76b512244ed6ca6b4d8f4babcb81 public boolean asynchronous; public EngineMode engineMode; diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index ad5e538b2498ed0e6d0cb79a6d5055732cddbc14..5d1fa08f6973ec12198b063d210b31615adbfeaa 100644 +index 46ad4612a1bd5ab005450645f69b0cb9f6f18aa7..6af8aeae5d1312c526622bc7e74e977dcb29a5b0 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java -@@ -957,6 +957,13 @@ public class WorldServer extends World { +@@ -960,6 +960,13 @@ public class WorldServer extends World { EnumCreatureType enumcreaturetype = entity.getEntityType().e(); if (enumcreaturetype != EnumCreatureType.MISC && this.getChunkProvider().b(entity)) { diff --git a/Spigot-Server-Patches/0387-Mark-entities-as-being-ticked-when-notifying-navigat.patch b/Spigot-Server-Patches/0387-Mark-entities-as-being-ticked-when-notifying-navigat.patch index e734c4b71c..ebc184d782 100644 --- a/Spigot-Server-Patches/0387-Mark-entities-as-being-ticked-when-notifying-navigat.patch +++ b/Spigot-Server-Patches/0387-Mark-entities-as-being-ticked-when-notifying-navigat.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Mark entities as being ticked when notifying navigation diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index 5d1fa08f6973ec12198b063d210b31615adbfeaa..8561f96b9a10cc2faa3ec1087a05ddb4c6164938 100644 +index 6af8aeae5d1312c526622bc7e74e977dcb29a5b0..17e2399fdb1cecc86b5450b7abbacd738f9445cf 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java -@@ -1410,6 +1410,7 @@ public class WorldServer extends World { +@@ -1413,6 +1413,7 @@ public class WorldServer extends World { VoxelShape voxelshape1 = iblockdata1.getCollisionShape(this, blockposition); if (VoxelShapes.c(voxelshape, voxelshape1, OperatorBoolean.NOT_SAME)) { @@ -16,7 +16,7 @@ index 5d1fa08f6973ec12198b063d210b31615adbfeaa..8561f96b9a10cc2faa3ec1087a05ddb4 Iterator iterator = this.navigators.iterator(); while (iterator.hasNext()) { -@@ -1420,6 +1421,7 @@ public class WorldServer extends World { +@@ -1423,6 +1424,7 @@ public class WorldServer extends World { } } diff --git a/Spigot-Server-Patches/0390-Asynchronous-chunk-IO-and-loading.patch b/Spigot-Server-Patches/0390-Asynchronous-chunk-IO-and-loading.patch index 879140cf09..9f1b4b8ce9 100644 --- a/Spigot-Server-Patches/0390-Asynchronous-chunk-IO-and-loading.patch +++ b/Spigot-Server-Patches/0390-Asynchronous-chunk-IO-and-loading.patch @@ -3922,7 +3922,7 @@ index c999f8c9bf8a59e19b3d6d1b7ad8b5fb6e48b928..b59ef1a63338aa150d39e8014e12b227 HAS_SPACE(VillagePlaceRecord::d), IS_OCCUPIED(VillagePlaceRecord::e), ANY((villageplacerecord) -> { diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index 8561f96b9a10cc2faa3ec1087a05ddb4c6164938..30dbf95a02bd8e68471400245b46189f8e0560cc 100644 +index 17e2399fdb1cecc86b5450b7abbacd738f9445cf..90d7f77b49a7bf11d40118a9e1d5718fcf2b3be4 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java @@ -82,6 +82,79 @@ public class WorldServer extends World { @@ -4014,7 +4014,7 @@ index 8561f96b9a10cc2faa3ec1087a05ddb4c6164938..30dbf95a02bd8e68471400245b46189f } // CraftBukkit start -@@ -1673,7 +1748,10 @@ public class WorldServer extends World { +@@ -1676,7 +1751,10 @@ public class WorldServer extends World { } MCUtil.getSpiralOutChunks(spawn, radiusInBlocks >> 4).forEach(pair -> { diff --git a/Spigot-Server-Patches/0394-Do-less-work-if-we-have-a-custom-Bukkit-generator.patch b/Spigot-Server-Patches/0394-Do-less-work-if-we-have-a-custom-Bukkit-generator.patch index 851b0e02df..bfc61d82ca 100644 --- a/Spigot-Server-Patches/0394-Do-less-work-if-we-have-a-custom-Bukkit-generator.patch +++ b/Spigot-Server-Patches/0394-Do-less-work-if-we-have-a-custom-Bukkit-generator.patch @@ -7,10 +7,10 @@ If the Bukkit generator already has a spawn, use it immediately instead of spending time generating one that we won't use diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index 2fa1b86adf89bb9b2398806bf30b0a6e436a4577..731f6a83200b4f7608fe1f1f3f0e04d827913e72 100644 +index d6cb21e3c3d1ccfd27f684a701bf7f74648634f8..b5b8fdcab1c84b52d56ed67bbded745763915ff7 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java -@@ -811,12 +811,13 @@ public class WorldServer extends World { +@@ -814,12 +814,13 @@ public class WorldServer extends World { } else if (this.worldData.getType() == WorldType.DEBUG_ALL_BLOCK_STATES) { this.worldData.setSpawn(BlockPosition.ZERO.up()); } else { @@ -30,7 +30,7 @@ index 2fa1b86adf89bb9b2398806bf30b0a6e436a4577..731f6a83200b4f7608fe1f1f3f0e04d8 // CraftBukkit start if (this.generator != null) { Random rand = new Random(this.getSeed()); -@@ -833,6 +834,13 @@ public class WorldServer extends World { +@@ -836,6 +837,13 @@ public class WorldServer extends World { } // CraftBukkit end diff --git a/Spigot-Server-Patches/0396-implement-optional-per-player-mob-spawns.patch b/Spigot-Server-Patches/0396-implement-optional-per-player-mob-spawns.patch index a4aef1fd1b..f3c718b0fd 100644 --- a/Spigot-Server-Patches/0396-implement-optional-per-player-mob-spawns.patch +++ b/Spigot-Server-Patches/0396-implement-optional-per-player-mob-spawns.patch @@ -755,10 +755,10 @@ index fdac5bb3a2d4a73035e1d914979b87fc224b6b20..58bbf2f9d2ec91715051d40e108e1606 @Nullable diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index e7747396c19c432de59213a440ba0dd692daadae..95c3ee7387977efe87f2c7eba017489823ba1390 100644 +index b5b8fdcab1c84b52d56ed67bbded745763915ff7..33819510e43d91025cb0c4eae45d840fb9d456ff 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java -@@ -1028,7 +1028,20 @@ public class WorldServer extends World { +@@ -1031,7 +1031,20 @@ public class WorldServer extends World { } public Object2IntMap l() { @@ -780,7 +780,7 @@ index e7747396c19c432de59213a440ba0dd692daadae..95c3ee7387977efe87f2c7eba0174898 ObjectIterator objectiterator = this.entitiesById.values().iterator(); while (objectiterator.hasNext()) { -@@ -1053,11 +1066,16 @@ public class WorldServer extends World { +@@ -1056,11 +1069,16 @@ public class WorldServer extends World { continue; } // Paper end diff --git a/Spigot-Server-Patches/0448-Ensure-Entity-is-never-double-registered.patch b/Spigot-Server-Patches/0448-Ensure-Entity-is-never-double-registered.patch index 54ac3f79fe..33d203f23b 100644 --- a/Spigot-Server-Patches/0448-Ensure-Entity-is-never-double-registered.patch +++ b/Spigot-Server-Patches/0448-Ensure-Entity-is-never-double-registered.patch @@ -11,7 +11,7 @@ Vs behavior of non ticking of just overwriting state. We will now simply log a warning when this happens instead of crashing the server. diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java -index 00df89d65099cbdd96c77ac26c892f05a2c37d79..0dbe2dce111673f94d0618c7ac80262189f2926f 100644 +index 7bdd3f19b2bc51c4f995d42fcd47e0e315310bff..7434f859f7f9acff0f881ff594c8dffdfa249c76 100644 --- a/src/main/java/net/minecraft/server/Entity.java +++ b/src/main/java/net/minecraft/server/Entity.java @@ -59,6 +59,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke @@ -23,7 +23,7 @@ index 00df89d65099cbdd96c77ac26c892f05a2c37d79..0dbe2dce111673f94d0618c7ac802621 private boolean locked = false; @Override diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index 5173731dc55db416a312e13afd09e4e69d829e45..3fc25183ca41a0a575334d02a4ae9db4da41348b 100644 +index 53da79da59f1940eafbd2eaae172e596690b0fdb..d8045367af230b21a0d402301fc65f77823a3bc7 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java @@ -532,6 +532,7 @@ public class WorldServer extends World { @@ -34,7 +34,7 @@ index 5173731dc55db416a312e13afd09e4e69d829e45..3fc25183ca41a0a575334d02a4ae9db4 this.registerEntity(entity); } } // Paper - timings -@@ -1353,6 +1354,19 @@ public class WorldServer extends World { +@@ -1356,6 +1357,19 @@ public class WorldServer extends World { public void unregisterEntity(Entity entity) { org.spigotmc.AsyncCatcher.catchOp("entity unregister"); // Spigot @@ -54,7 +54,7 @@ index 5173731dc55db416a312e13afd09e4e69d829e45..3fc25183ca41a0a575334d02a4ae9db4 // Spigot start if ( entity instanceof EntityHuman ) { -@@ -1413,9 +1427,21 @@ public class WorldServer extends World { +@@ -1416,9 +1430,21 @@ public class WorldServer extends World { private void registerEntity(Entity entity) { org.spigotmc.AsyncCatcher.catchOp("entity register"); // Spigot diff --git a/Spigot-Server-Patches/0449-Fix-unregistering-entities-from-unloading-chunks.patch b/Spigot-Server-Patches/0449-Fix-unregistering-entities-from-unloading-chunks.patch index 587f483765..7d6f3b92a2 100644 --- a/Spigot-Server-Patches/0449-Fix-unregistering-entities-from-unloading-chunks.patch +++ b/Spigot-Server-Patches/0449-Fix-unregistering-entities-from-unloading-chunks.patch @@ -15,10 +15,10 @@ Combine that with a buggy detail of the previous implementation of the Dupe UUID patch, then this was the likely source of the "Ghost entities" diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index 3fc25183ca41a0a575334d02a4ae9db4da41348b..9fbe8fa1b2bb98b45fb406fcaf146d0e0b34c0ef 100644 +index d8045367af230b21a0d402301fc65f77823a3bc7..5d14cd2153d151c240c815e7d52262ce1c499b1a 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java -@@ -1506,9 +1506,9 @@ public class WorldServer extends World { +@@ -1509,9 +1509,9 @@ public class WorldServer extends World { } private void removeEntityFromChunk(Entity entity) { diff --git a/Spigot-Server-Patches/0452-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch b/Spigot-Server-Patches/0452-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch index 21b7810714..017ab7c0c6 100644 --- a/Spigot-Server-Patches/0452-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch +++ b/Spigot-Server-Patches/0452-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch @@ -26,10 +26,10 @@ index 6eb055913177b0c01a027b2b356190dc561072c5..4beae504c875767ff00e26461fe72404 if (!(entity instanceof EntityLightning)) { EntityTypes entitytypes = entity.getEntityType(); diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index 9fbe8fa1b2bb98b45fb406fcaf146d0e0b34c0ef..2a7a47c6707c349af55ccd70eb3b8c48387c391a 100644 +index 5d14cd2153d151c240c815e7d52262ce1c499b1a..3979f151f067a62e45211c9f11e47e36dbe16b31 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java -@@ -1472,7 +1472,7 @@ public class WorldServer extends World { +@@ -1475,7 +1475,7 @@ public class WorldServer extends World { } } @@ -38,7 +38,7 @@ index 9fbe8fa1b2bb98b45fb406fcaf146d0e0b34c0ef..2a7a47c6707c349af55ccd70eb3b8c48 // CraftBukkit start - SPIGOT-5278 if (entity instanceof EntityDrowned) { this.navigators.add(((EntityDrowned) entity).navigationWater); -@@ -1483,6 +1483,7 @@ public class WorldServer extends World { +@@ -1486,6 +1486,7 @@ public class WorldServer extends World { this.navigators.add(((EntityInsentient) entity).getNavigation()); } entity.valid = true; // CraftBukkit