From fbe895823738e0ec677f1103e9ab4fa4e5fa0613 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Wed, 6 May 2020 03:44:47 -0400 Subject: [PATCH] Use distance map to optimise entity tracker / Misc Utils Use the distance map to find candidate players for tracking. This also ports a few utility changes from Tuinity --- ...ies-option-to-debug-dupe-uuid-issues.patch | 4 +- .../Add-exception-reporting-event.patch | 4 +- ...ntom-creative-and-insomniac-controls.patch | 2 +- ...dd-some-Debug-to-Chunk-Entity-slices.patch | 2 +- ...allbacks-to-schedule-for-Callback-Ex.patch | 2 +- Spigot-Server-Patches/Anti-Xray.patch | 4 +- .../Asynchronous-chunk-IO-and-loading.patch | 4 +- ...opper-searches-if-there-are-no-items.patch | 2 +- .../Configurable-Chunk-Inhabited-Time.patch | 2 +- ...le-Keep-Spawn-Loaded-range-per-world.patch | 2 +- ...ions-until-after-entity-ticking-is-d.patch | 2 +- ...move-existing-players-to-world-spawn.patch | 2 +- .../Don-t-tick-dead-players.patch | 2 +- .../Duplicate-UUID-Resolve-Option.patch | 6 +- ...re-Entity-is-never-double-registered.patch | 2 +- ...Entity-AddTo-RemoveFrom-World-Events.patch | 2 +- Spigot-Server-Patches/Entity-Origin-API.patch | 2 +- .../Entity-getEntitySpawnReason.patch | 2 +- ...ld.spawnParticle-API-and-add-Builder.patch | 2 +- ...-Chunk-Post-Processing-deadlock-risk.patch | 2 +- .../Fix-Double-World-Add-issues.patch | 2 +- ...g-Broken-behavior-of-PlayerJoinEvent.patch | 4 +- .../Fix-World-isChunkGenerated-calls.patch | 2 +- ...h-entity-loss-due-to-unloaded-chunks.patch | 2 +- ...ering-entities-from-unloading-chunks.patch | 2 +- ...ead-Entities-in-entityList-iteration.patch | 4 +- ...Priority-Urgency-System-for-World-Ge.patch | 2 +- .../Implement-Mob-Goal-API.patch | 22 +- .../Implement-Player-Client-Options-API.patch | 6 +- ...item-frames-performance-and-bug-fixe.patch | 2 +- .../Increase-Light-Queue-Size.patch | 6 +- .../InventoryCloseEvent-Reason-API.patch | 2 +- ...mit-lightning-strike-effect-distance.patch | 2 +- ...Load-Chunks-for-Login-Asynchronously.patch | 2 +- Spigot-Server-Patches/MC-Utils.patch | 367 ++++++++++++++--- ...more-aggressive-in-the-chunk-unload-.patch | 2 +- ...-anytime-entities-change-to-guarante.patch | 2 +- ...-being-ticked-when-notifying-navigat.patch | 2 +- ...asks-Speed-up-processing-of-chunk-lo.patch | 2 +- .../Optimise-Chunk-getFluid.patch | 2 +- ...imise-entity-hard-collision-checking.patch | 4 +- .../Optimise-random-block-ticking.patch | 6 +- ...hunkMap-memory-use-for-visibleChunks.patch | 2 +- ...Location-getType-and-getBlockData-fo.patch | 2 +- ...tion-to-remove-corrupt-tile-entities.patch | 2 +- ...layer-View-Distance-API-placeholders.patch | 14 +- ...spawn-settings-and-per-player-option.patch | 4 +- .../PlayerNaturallySpawnCreaturesEvent.patch | 2 +- ...-PlayerChunkMap-adds-crashing-server.patch | 4 +- ...revent-Saving-Bad-entities-to-chunks.patch | 2 +- ...vent-opening-inventories-when-frozen.patch | 2 +- ...nilla-entity-warnings-for-duplicates.patch | 2 +- ...educe-entity-tracker-updates-on-move.patch | 211 ---------- ...ve-invalid-mob-spawner-tile-entities.patch | 2 +- ...Remove-unused-World-Tile-Entity-List.patch | 2 +- ...sition-the-first-time-an-entity-is-s.patch | 2 +- ...ets-from-world-player-list-not-serve.patch | 2 +- .../Speedup-BlockPos-by-fixing-inlining.patch | 2 +- ...ts-for-each-Entity-Block-Entity-Type.patch | 2 +- ...to-current-Chunk-for-Entity-and-Bloc.patch | 2 +- Spigot-Server-Patches/Timings-v2.patch | 6 +- .../Tracking-Range-Improvements.patch | 2 +- ...Status-cache-when-saving-protochunks.patch | 2 +- ...tance-map-to-optimise-entity-tracker.patch | 378 ++++++++++++++++++ ...PickItem-Packet-and-kick-for-invalid.patch | 2 +- ...ement-optional-per-player-mob-spawns.patch | 4 +- .../incremental-chunk-saving.patch | 6 +- 67 files changed, 802 insertions(+), 358 deletions(-) delete mode 100644 Spigot-Server-Patches/Reduce-entity-tracker-updates-on-move.patch create mode 100644 Spigot-Server-Patches/Use-distance-map-to-optimise-entity-tracker.patch diff --git a/Spigot-Server-Patches/Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch b/Spigot-Server-Patches/Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch index 7cf8434207..05457c2200 100644 --- a/Spigot-Server-Patches/Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch +++ b/Spigot-Server-Patches/Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch @@ -19,7 +19,7 @@ index 2ac396dd17..3043b87cf7 100644 if (bukkitEntity == null) { bukkitEntity = CraftEntity.getEntity(world.getServer(), this); diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java -index 175734b50c..2c7e611663 100644 +index 7804cc0f6a..4ee26ff08f 100644 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { @@ -52,7 +52,7 @@ index 2f57c7bc76..a1c33c525c 100644 public boolean captureBlockStates = false; public boolean captureTreeGeneration = false; diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index 4cbf390ce0..6ce7f77a5e 100644 +index 25e2a6580a..02d9c754b1 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 { diff --git a/Spigot-Server-Patches/Add-exception-reporting-event.patch b/Spigot-Server-Patches/Add-exception-reporting-event.patch index 0484b69408..0151a78d68 100644 --- a/Spigot-Server-Patches/Add-exception-reporting-event.patch +++ b/Spigot-Server-Patches/Add-exception-reporting-event.patch @@ -49,7 +49,7 @@ index 0000000000..f699ce18ca + } +} diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java -index 56d740fcad..39e77f8248 100644 +index 687e609cab..8f3eee5ea8 100644 --- a/src/main/java/net/minecraft/server/Chunk.java +++ b/src/main/java/net/minecraft/server/Chunk.java @@ -0,0 +0,0 @@ @@ -121,7 +121,7 @@ index c9c2b00251..1422503e11 100644 } // CraftBukkit end diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java -index d49f456f73..a79e4cef4a 100644 +index eece2f689c..6374bf8785 100644 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { diff --git a/Spigot-Server-Patches/Add-phantom-creative-and-insomniac-controls.patch b/Spigot-Server-Patches/Add-phantom-creative-and-insomniac-controls.patch index e4e2f89dc1..d99b0c08e0 100644 --- a/Spigot-Server-Patches/Add-phantom-creative-and-insomniac-controls.patch +++ b/Spigot-Server-Patches/Add-phantom-creative-and-insomniac-controls.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add phantom creative and insomniac controls diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -index 88a45e517c..fc189ebc96 100644 +index 3c0468bc44..bfb52d75c7 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 { diff --git a/Spigot-Server-Patches/Add-some-Debug-to-Chunk-Entity-slices.patch b/Spigot-Server-Patches/Add-some-Debug-to-Chunk-Entity-slices.patch index 4f9141d86c..8276a5749a 100644 --- a/Spigot-Server-Patches/Add-some-Debug-to-Chunk-Entity-slices.patch +++ b/Spigot-Server-Patches/Add-some-Debug-to-Chunk-Entity-slices.patch @@ -9,7 +9,7 @@ This should hopefully avoid duplicate entities ever being created if the entity was to end up in 2 different chunk slices diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java -index 803afed60d..80b5013d95 100644 +index 6a40dddf46..0afa8a7ebd 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 { diff --git a/Spigot-Server-Patches/Allow-multiple-callbacks-to-schedule-for-Callback-Ex.patch b/Spigot-Server-Patches/Allow-multiple-callbacks-to-schedule-for-Callback-Ex.patch index 69c974c9f8..b8251a146b 100644 --- a/Spigot-Server-Patches/Allow-multiple-callbacks-to-schedule-for-Callback-Ex.patch +++ b/Spigot-Server-Patches/Allow-multiple-callbacks-to-schedule-for-Callback-Ex.patch @@ -14,7 +14,7 @@ Use an ArrayDeque to store this Queue We make sure to also implement a pattern that is recursion safe too. diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java -index 3f4a3205a4..aabb9220db 100644 +index a06c0327df..e08a3bd96c 100644 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { diff --git a/Spigot-Server-Patches/Anti-Xray.patch b/Spigot-Server-Patches/Anti-Xray.patch index 0bbec5fc2a..9677c9a3a6 100644 --- a/Spigot-Server-Patches/Anti-Xray.patch +++ b/Spigot-Server-Patches/Anti-Xray.patch @@ -1181,7 +1181,7 @@ index 0000000000..37093419cf + } +} diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java -index 4b77934c39..9ce9542b80 100644 +index af0d6aff4d..472d3a4c03 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 { @@ -1550,7 +1550,7 @@ index 040d4b41ea..f1620ba80e 100644 this.a(new PacketPlayOutMultiBlockChange(this.dirtyCount, this.dirtyBlocks, chunk), false); diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java -index c9c25cdb8e..9c627bf3b4 100644 +index 9171785ad5..eb29d0e956 100644 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { diff --git a/Spigot-Server-Patches/Asynchronous-chunk-IO-and-loading.patch b/Spigot-Server-Patches/Asynchronous-chunk-IO-and-loading.patch index cb7bd72f4d..1d971c8caa 100644 --- a/Spigot-Server-Patches/Asynchronous-chunk-IO-and-loading.patch +++ b/Spigot-Server-Patches/Asynchronous-chunk-IO-and-loading.patch @@ -3099,7 +3099,7 @@ index f1620ba80e..74e6b8b973 100644 completablefuture = (CompletableFuture) this.statusFutures.get(i); if (completablefuture != null) { diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java -index 9c627bf3b4..19603343b2 100644 +index eb29d0e956..43abdb47fd 100644 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { @@ -3983,7 +3983,7 @@ index c999f8c9bf..b59ef1a633 100644 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 e3913952d9..3db0ad0a46 100644 +index 8561f96b9a..c0476f69e4 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 { diff --git a/Spigot-Server-Patches/Avoid-hopper-searches-if-there-are-no-items.patch b/Spigot-Server-Patches/Avoid-hopper-searches-if-there-are-no-items.patch index 05f2720b79..3716bafb73 100644 --- a/Spigot-Server-Patches/Avoid-hopper-searches-if-there-are-no-items.patch +++ b/Spigot-Server-Patches/Avoid-hopper-searches-if-there-are-no-items.patch @@ -14,7 +14,7 @@ And since minecart hoppers are used _very_ rarely near we can avoid alot of sear Combined, this adds up a lot. diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java -index 9ce9542b80..a23dfeb63d 100644 +index 472d3a4c03..42eede6781 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 { diff --git a/Spigot-Server-Patches/Configurable-Chunk-Inhabited-Time.patch b/Spigot-Server-Patches/Configurable-Chunk-Inhabited-Time.patch index 9ef84d4741..d7c566bf10 100644 --- a/Spigot-Server-Patches/Configurable-Chunk-Inhabited-Time.patch +++ b/Spigot-Server-Patches/Configurable-Chunk-Inhabited-Time.patch @@ -30,7 +30,7 @@ index 6ef0e1399e..5872e6b171 100644 + } } diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java -index 7ddf6592f7..d1761ff3c4 100644 +index 4b162a768e..6694d0e36c 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 { diff --git a/Spigot-Server-Patches/Configurable-Keep-Spawn-Loaded-range-per-world.patch b/Spigot-Server-Patches/Configurable-Keep-Spawn-Loaded-range-per-world.patch index 71151aabf0..1d34dc3c26 100644 --- a/Spigot-Server-Patches/Configurable-Keep-Spawn-Loaded-range-per-world.patch +++ b/Spigot-Server-Patches/Configurable-Keep-Spawn-Loaded-range-per-world.patch @@ -102,7 +102,7 @@ index 3868572aed..ae77805f71 100644 @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 f9ee9afe3a..389c9d03a1 100644 +index 081df240f3..ce506e0e12 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 { diff --git a/Spigot-Server-Patches/Delay-unsafe-actions-until-after-entity-ticking-is-d.patch b/Spigot-Server-Patches/Delay-unsafe-actions-until-after-entity-ticking-is-d.patch index 9e7d2e95a5..b548481931 100644 --- a/Spigot-Server-Patches/Delay-unsafe-actions-until-after-entity-ticking-is-d.patch +++ b/Spigot-Server-Patches/Delay-unsafe-actions-until-after-entity-ticking-is-d.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Delay unsafe actions until after entity ticking is done This will help prevent many cases of unregistering entities during entity ticking diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index dc01fb494d..d13dc8fce9 100644 +index 9b5f24c262..b3785775ec 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 { diff --git a/Spigot-Server-Patches/Don-t-move-existing-players-to-world-spawn.patch b/Spigot-Server-Patches/Don-t-move-existing-players-to-world-spawn.patch index 54207adac1..7dac31415b 100644 --- a/Spigot-Server-Patches/Don-t-move-existing-players-to-world-spawn.patch +++ b/Spigot-Server-Patches/Don-t-move-existing-players-to-world-spawn.patch @@ -10,7 +10,7 @@ larger than the keep loaded range. By skipping this, we avoid potential for a large spike on server start. diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java -index a16a8c10a2..50886c1374 100644 +index aa9c903aa8..d51af68a92 100644 --- a/src/main/java/net/minecraft/server/EntityPlayer.java +++ b/src/main/java/net/minecraft/server/EntityPlayer.java @@ -0,0 +0,0 @@ public class EntityPlayer extends EntityHuman implements ICrafting { diff --git a/Spigot-Server-Patches/Don-t-tick-dead-players.patch b/Spigot-Server-Patches/Don-t-tick-dead-players.patch index 6ab019b3b7..79161f523d 100644 --- a/Spigot-Server-Patches/Don-t-tick-dead-players.patch +++ b/Spigot-Server-Patches/Don-t-tick-dead-players.patch @@ -7,7 +7,7 @@ Causes sync chunk loads and who knows what all else. This is safe because Spectators are skipped in unloaded chunks too in vanilla. diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java -index c6474aa0f8..a16a8c10a2 100644 +index 900631ebe0..aa9c903aa8 100644 --- a/src/main/java/net/minecraft/server/EntityPlayer.java +++ b/src/main/java/net/minecraft/server/EntityPlayer.java @@ -0,0 +0,0 @@ public class EntityPlayer extends EntityHuman implements ICrafting { diff --git a/Spigot-Server-Patches/Duplicate-UUID-Resolve-Option.patch b/Spigot-Server-Patches/Duplicate-UUID-Resolve-Option.patch index 6b6e7d5e35..89a5a213a4 100644 --- a/Spigot-Server-Patches/Duplicate-UUID-Resolve-Option.patch +++ b/Spigot-Server-Patches/Duplicate-UUID-Resolve-Option.patch @@ -81,7 +81,7 @@ index 4ba72275b9..572679e4d1 100644 + } } diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java -index f47ed1947e..7bcdbe713d 100644 +index 8e9ddca049..165cb994e8 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 { @@ -105,7 +105,7 @@ index 030c9992eb..fd6dad8437 100644 this.uniqueID = uuid; this.am = this.uniqueID.toString(); diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java -index 2c7e611663..3c237b259e 100644 +index 4ee26ff08f..1d255ce383 100644 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java @@ -0,0 +0,0 @@ @@ -197,7 +197,7 @@ index 2c7e611663..3c237b259e 100644 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 e34ea3d098..f9ee9afe3a 100644 +index 6da2392915..081df240f3 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java @@ -0,0 +0,0 @@ package net.minecraft.server; diff --git a/Spigot-Server-Patches/Ensure-Entity-is-never-double-registered.patch b/Spigot-Server-Patches/Ensure-Entity-is-never-double-registered.patch index 618dc9ceb1..9c4a133582 100644 --- a/Spigot-Server-Patches/Ensure-Entity-is-never-double-registered.patch +++ b/Spigot-Server-Patches/Ensure-Entity-is-never-double-registered.patch @@ -23,7 +23,7 @@ index 00df89d650..0dbe2dce11 100644 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 9b9e242432..f80c80957a 100644 +index 5173731dc5..3fc25183ca 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 { diff --git a/Spigot-Server-Patches/Entity-AddTo-RemoveFrom-World-Events.patch b/Spigot-Server-Patches/Entity-AddTo-RemoveFrom-World-Events.patch index 92dfb0f39c..c7ede3193a 100644 --- a/Spigot-Server-Patches/Entity-AddTo-RemoveFrom-World-Events.patch +++ b/Spigot-Server-Patches/Entity-AddTo-RemoveFrom-World-Events.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Entity AddTo/RemoveFrom World Events diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index 9d0edf5382..fd42f34004 100644 +index 3769f0533d..f8d1cb0231 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 { diff --git a/Spigot-Server-Patches/Entity-Origin-API.patch b/Spigot-Server-Patches/Entity-Origin-API.patch index 8fe0891019..dac5bfb98b 100644 --- a/Spigot-Server-Patches/Entity-Origin-API.patch +++ b/Spigot-Server-Patches/Entity-Origin-API.patch @@ -101,7 +101,7 @@ index 5406f4c40f..d778eac45d 100644 if (i >= 0 && i < this.list.size()) { NBTBase nbtbase = (NBTBase) this.list.get(i); diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index 6810d49b17..450b414298 100644 +index 38a71bca2f..351825ebec 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 { diff --git a/Spigot-Server-Patches/Entity-getEntitySpawnReason.patch b/Spigot-Server-Patches/Entity-getEntitySpawnReason.patch index 16e666d158..7032e24205 100644 --- a/Spigot-Server-Patches/Entity-getEntitySpawnReason.patch +++ b/Spigot-Server-Patches/Entity-getEntitySpawnReason.patch @@ -72,7 +72,7 @@ index e9908cd01f..7745e70d2d 100644 }); diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index 43565dd92c..f7a1fad9c1 100644 +index a75034079b..955003d5f8 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 { diff --git a/Spigot-Server-Patches/Expand-World.spawnParticle-API-and-add-Builder.patch b/Spigot-Server-Patches/Expand-World.spawnParticle-API-and-add-Builder.patch index 092380eb8d..c93b6742e8 100644 --- a/Spigot-Server-Patches/Expand-World.spawnParticle-API-and-add-Builder.patch +++ b/Spigot-Server-Patches/Expand-World.spawnParticle-API-and-add-Builder.patch @@ -10,7 +10,7 @@ Adds an option to control the force mode of the particle. This adds a new Builder API which is much friendlier to use. diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index eb99f3a967..da391e945c 100644 +index 7417725363..60f936f2e5 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 { diff --git a/Spigot-Server-Patches/Fix-Chunk-Post-Processing-deadlock-risk.patch b/Spigot-Server-Patches/Fix-Chunk-Post-Processing-deadlock-risk.patch index f30fdf5019..c50cd9a7cb 100644 --- a/Spigot-Server-Patches/Fix-Chunk-Post-Processing-deadlock-risk.patch +++ b/Spigot-Server-Patches/Fix-Chunk-Post-Processing-deadlock-risk.patch @@ -37,7 +37,7 @@ index c2e4e4f6f1..78a8a3cc68 100644 } // CraftBukkit end diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java -index 6fa70eb08d..0e652625bb 100644 +index 22550f74df..cc400a9a84 100644 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { diff --git a/Spigot-Server-Patches/Fix-Double-World-Add-issues.patch b/Spigot-Server-Patches/Fix-Double-World-Add-issues.patch index ed0164216d..5813581d79 100644 --- a/Spigot-Server-Patches/Fix-Double-World-Add-issues.patch +++ b/Spigot-Server-Patches/Fix-Double-World-Add-issues.patch @@ -8,7 +8,7 @@ Vanilla will double add Spider Jockeys to the world, so ignore already added. Also add debug if something else tries to, and abort before world gets bad state diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index 40c9cba760..3004270455 100644 +index 6271fb2092..3508fd7084 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 { diff --git a/Spigot-Server-Patches/Fix-Longstanding-Broken-behavior-of-PlayerJoinEvent.patch b/Spigot-Server-Patches/Fix-Longstanding-Broken-behavior-of-PlayerJoinEvent.patch index f8aa6af978..02458b8412 100644 --- a/Spigot-Server-Patches/Fix-Longstanding-Broken-behavior-of-PlayerJoinEvent.patch +++ b/Spigot-Server-Patches/Fix-Longstanding-Broken-behavior-of-PlayerJoinEvent.patch @@ -28,7 +28,7 @@ receives a deterministic result, and should no longer require 1 tick delays anymore. diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java -index c108a38018..a48e113b53 100644 +index bf2ba0548d..45df816980 100644 --- a/src/main/java/net/minecraft/server/EntityPlayer.java +++ b/src/main/java/net/minecraft/server/EntityPlayer.java @@ -0,0 +0,0 @@ public class EntityPlayer extends EntityHuman implements ICrafting { @@ -40,7 +40,7 @@ index c108a38018..a48e113b53 100644 // CraftBukkit end public PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java -index 0e652625bb..3f4a3205a4 100644 +index cc400a9a84..a06c0327df 100644 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { diff --git a/Spigot-Server-Patches/Fix-World-isChunkGenerated-calls.patch b/Spigot-Server-Patches/Fix-World-isChunkGenerated-calls.patch index bf58dd4570..8a39a224d7 100644 --- a/Spigot-Server-Patches/Fix-World-isChunkGenerated-calls.patch +++ b/Spigot-Server-Patches/Fix-World-isChunkGenerated-calls.patch @@ -132,7 +132,7 @@ index 3d255b1964..040d4b41ea 100644 public CompletableFuture> getStatusFutureUnchecked(ChunkStatus chunkstatus) { diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java -index 4682dca9de..405f57874e 100644 +index 4f5b516144..1d517fd1ae 100644 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { diff --git a/Spigot-Server-Patches/Fix-issues-with-entity-loss-due-to-unloaded-chunks.patch b/Spigot-Server-Patches/Fix-issues-with-entity-loss-due-to-unloaded-chunks.patch index 54b291061f..5e6db19d33 100644 --- a/Spigot-Server-Patches/Fix-issues-with-entity-loss-due-to-unloaded-chunks.patch +++ b/Spigot-Server-Patches/Fix-issues-with-entity-loss-due-to-unloaded-chunks.patch @@ -19,7 +19,7 @@ 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 f7a1fad9c1..e34ea3d098 100644 +index 955003d5f8..6da2392915 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 { diff --git a/Spigot-Server-Patches/Fix-unregistering-entities-from-unloading-chunks.patch b/Spigot-Server-Patches/Fix-unregistering-entities-from-unloading-chunks.patch index 20ac51d672..c8a5863cf1 100644 --- a/Spigot-Server-Patches/Fix-unregistering-entities-from-unloading-chunks.patch +++ b/Spigot-Server-Patches/Fix-unregistering-entities-from-unloading-chunks.patch @@ -15,7 +15,7 @@ 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 f80c80957a..3f8f40018d 100644 +index 3fc25183ca..9fbe8fa1b2 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 { 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 c9d63a2cbc..83af251ebe 100644 --- a/Spigot-Server-Patches/Ignore-Dead-Entities-in-entityList-iteration.patch +++ b/Spigot-Server-Patches/Ignore-Dead-Entities-in-entityList-iteration.patch @@ -23,7 +23,7 @@ index b839769cea..5acad8e44f 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 80b5013d95..f47ed1947e 100644 +index 0afa8a7ebd..8e9ddca049 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 { @@ -63,7 +63,7 @@ index 838aa7da69..35d22ec027 100644 public float getBukkitYaw() { return this.yaw; diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index 87762b1725..8d292604c3 100644 +index d1424325d5..f071b61195 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 { diff --git a/Spigot-Server-Patches/Implement-Chunk-Priority-Urgency-System-for-World-Ge.patch b/Spigot-Server-Patches/Implement-Chunk-Priority-Urgency-System-for-World-Ge.patch index 63ca9768c8..f893d65d2c 100644 --- a/Spigot-Server-Patches/Implement-Chunk-Priority-Urgency-System-for-World-Ge.patch +++ b/Spigot-Server-Patches/Implement-Chunk-Priority-Urgency-System-for-World-Ge.patch @@ -197,7 +197,7 @@ index 04b97cec29..568fbbd5f2 100644 private void d(int i) { diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java -index fb7bbe8744..6fa70eb08d 100644 +index db5a35598d..22550f74df 100644 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { diff --git a/Spigot-Server-Patches/Implement-Mob-Goal-API.patch b/Spigot-Server-Patches/Implement-Mob-Goal-API.patch index c3812d333b..b4f6947c38 100644 --- a/Spigot-Server-Patches/Implement-Mob-Goal-API.patch +++ b/Spigot-Server-Patches/Implement-Mob-Goal-API.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Implement Mob Goal API diff --git a/pom.xml b/pom.xml -index bc8438ae1..0c0051f7f 100644 +index bc8438ae1a..0c0051f7f2 100644 --- a/pom.xml +++ b/pom.xml @@ -0,0 +0,0 @@ @@ -24,7 +24,7 @@ index bc8438ae1..0c0051f7f 100644 diff --git a/src/main/java/com/destroystokyo/paper/entity/ai/MobGoalHelper.java b/src/main/java/com/destroystokyo/paper/entity/ai/MobGoalHelper.java new file mode 100644 -index 000000000..d6ee94107 +index 0000000000..d6ee941078 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/entity/ai/MobGoalHelper.java @@ -0,0 +0,0 @@ @@ -359,7 +359,7 @@ index 000000000..d6ee94107 +} diff --git a/src/main/java/com/destroystokyo/paper/entity/ai/PaperCustomGoal.java b/src/main/java/com/destroystokyo/paper/entity/ai/PaperCustomGoal.java new file mode 100644 -index 000000000..8e4dc2708 +index 0000000000..8e4dc2708d --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/entity/ai/PaperCustomGoal.java @@ -0,0 +0,0 @@ @@ -417,7 +417,7 @@ index 000000000..8e4dc2708 +} diff --git a/src/main/java/com/destroystokyo/paper/entity/ai/PaperMobGoals.java b/src/main/java/com/destroystokyo/paper/entity/ai/PaperMobGoals.java new file mode 100644 -index 000000000..d9df0236e +index 0000000000..d9df0236e8 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/entity/ai/PaperMobGoals.java @@ -0,0 +0,0 @@ @@ -659,7 +659,7 @@ index 000000000..d9df0236e +} diff --git a/src/main/java/com/destroystokyo/paper/entity/ai/PaperVanillaGoal.java b/src/main/java/com/destroystokyo/paper/entity/ai/PaperVanillaGoal.java new file mode 100644 -index 000000000..263e8c65b +index 0000000000..263e8c65b9 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/entity/ai/PaperVanillaGoal.java @@ -0,0 +0,0 @@ @@ -727,7 +727,7 @@ index 000000000..263e8c65b + } +} diff --git a/src/main/java/com/destroystokyo/paper/util/set/OptimizedSmallEnumSet.java b/src/main/java/com/destroystokyo/paper/util/set/OptimizedSmallEnumSet.java -index 9df0006c1..b3329c6fc 100644 +index 9df0006c1a..b3329c6fcd 100644 --- a/src/main/java/com/destroystokyo/paper/util/set/OptimizedSmallEnumSet.java +++ b/src/main/java/com/destroystokyo/paper/util/set/OptimizedSmallEnumSet.java @@ -0,0 +0,0 @@ public final class OptimizedSmallEnumSet> { @@ -740,7 +740,7 @@ index 9df0006c1..b3329c6fc 100644 + } } diff --git a/src/main/java/net/minecraft/server/PathfinderGoal.java b/src/main/java/net/minecraft/server/PathfinderGoal.java -index 93009d83f..2dfbecf39 100644 +index 93009d83f0..2dfbecf390 100644 --- a/src/main/java/net/minecraft/server/PathfinderGoal.java +++ b/src/main/java/net/minecraft/server/PathfinderGoal.java @@ -0,0 +0,0 @@ public abstract class PathfinderGoal { @@ -776,7 +776,7 @@ index 93009d83f..2dfbecf39 100644 this.goalTypes.clear(); this.goalTypes.addAllUnchecked(enumset); diff --git a/src/main/java/net/minecraft/server/PathfinderGoalSelector.java b/src/main/java/net/minecraft/server/PathfinderGoalSelector.java -index 84d2abbcb..a68fc11ec 100644 +index 84d2abbcb9..a68fc11ec6 100644 --- a/src/main/java/net/minecraft/server/PathfinderGoalSelector.java +++ b/src/main/java/net/minecraft/server/PathfinderGoalSelector.java @@ -0,0 +0,0 @@ public class PathfinderGoalSelector { @@ -815,7 +815,7 @@ index 84d2abbcb..a68fc11ec 100644 return this.d.stream().filter(PathfinderGoalWrapped::g); } diff --git a/src/main/java/net/minecraft/server/PathfinderGoalWrapped.java b/src/main/java/net/minecraft/server/PathfinderGoalWrapped.java -index 1b800c558..dee4e2bea 100644 +index 1b800c558f..dee4e2beac 100644 --- a/src/main/java/net/minecraft/server/PathfinderGoalWrapped.java +++ b/src/main/java/net/minecraft/server/PathfinderGoalWrapped.java @@ -0,0 +0,0 @@ import javax.annotation.Nullable; @@ -830,7 +830,7 @@ index 1b800c558..dee4e2bea 100644 public PathfinderGoalWrapped(int i, PathfinderGoal pathfindergoal) { diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 1647c0975..b89f99a66 100644 +index 1647c09756..b89f99a66f 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -0,0 +0,0 @@ public final class CraftServer implements Server { @@ -847,7 +847,7 @@ index 1647c0975..b89f99a66 100644 } diff --git a/src/test/java/com/destroystokyo/paper/entity/ai/VanillaMobGoalTest.java b/src/test/java/com/destroystokyo/paper/entity/ai/VanillaMobGoalTest.java new file mode 100644 -index 000000000..83d34761d +index 0000000000..83d34761d9 --- /dev/null +++ b/src/test/java/com/destroystokyo/paper/entity/ai/VanillaMobGoalTest.java @@ -0,0 +0,0 @@ diff --git a/Spigot-Server-Patches/Implement-Player-Client-Options-API.patch b/Spigot-Server-Patches/Implement-Player-Client-Options-API.patch index a2f3a5c228..7f3d557ba9 100644 --- a/Spigot-Server-Patches/Implement-Player-Client-Options-API.patch +++ b/Spigot-Server-Patches/Implement-Player-Client-Options-API.patch @@ -98,7 +98,7 @@ index c4d4334305..7df24be46e 100644 protected static final DataWatcherObject bs = DataWatcher.a(EntityHuman.class, DataWatcherRegistry.p); protected static final DataWatcherObject bt = DataWatcher.a(EntityHuman.class, DataWatcherRegistry.p); diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java -index 0c0224d1eb..c108a38018 100644 +index f453ccdb02..bf2ba0548d 100644 --- a/src/main/java/net/minecraft/server/EntityPlayer.java +++ b/src/main/java/net/minecraft/server/EntityPlayer.java @@ -0,0 +0,0 @@ package net.minecraft.server; @@ -154,7 +154,7 @@ index 8faebf9efe..4da6371381 100644 return this.e; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index e76f2b9c7f..3515b72682 100644 +index 6672feaf51..dcbda5b35a 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -0,0 +0,0 @@ @@ -176,7 +176,7 @@ index e76f2b9c7f..3515b72682 100644 import net.minecraft.server.EnumChatFormat; @@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player { public void setViewDistance(int viewDistance) { - throw new NotImplementedException("Per-Player View Distance APIs need further understanding to properly implement"); // TODO + throw new NotImplementedException("Per-Player View Distance APIs need further understanding to properly implement (There are per world view distances though!)"); // TODO } + + @Override diff --git a/Spigot-Server-Patches/Improve-Maps-in-item-frames-performance-and-bug-fixe.patch b/Spigot-Server-Patches/Improve-Maps-in-item-frames-performance-and-bug-fixe.patch index 30a2ca2ff1..4b4f523246 100644 --- a/Spigot-Server-Patches/Improve-Maps-in-item-frames-performance-and-bug-fixe.patch +++ b/Spigot-Server-Patches/Improve-Maps-in-item-frames-performance-and-bug-fixe.patch @@ -102,7 +102,7 @@ index a56ac3da80..2f1be1995d 100644 for ( org.bukkit.map.MapCursor cursor : render.cursors) { diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index 6f66c38650..40c9cba760 100644 +index f46da0e8a0..6271fb2092 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 { diff --git a/Spigot-Server-Patches/Increase-Light-Queue-Size.patch b/Spigot-Server-Patches/Increase-Light-Queue-Size.patch index da53bc18d0..a3066b6cf1 100644 --- a/Spigot-Server-Patches/Increase-Light-Queue-Size.patch +++ b/Spigot-Server-Patches/Increase-Light-Queue-Size.patch @@ -14,12 +14,12 @@ light engine on shutdown... The queue size only puts a cap on max loss, doesn't solve that problem. diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -index 659a011e97..88a45e517c 100644 +index 803be76772..3c0468bc44 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 { - private void trackerUpdateDistance() { - trackerUpdateDistance = getDouble("tracker-update-distance", trackerUpdateDistance); + private void zombieVillagerInfectionChance() { + zombieVillagerInfectionChance = getDouble("zombie-villager-infection-chance", zombieVillagerInfectionChance); } + + public int lightQueueSize = 20; diff --git a/Spigot-Server-Patches/InventoryCloseEvent-Reason-API.patch b/Spigot-Server-Patches/InventoryCloseEvent-Reason-API.patch index 1a3d144d42..5bddffdd6c 100644 --- a/Spigot-Server-Patches/InventoryCloseEvent-Reason-API.patch +++ b/Spigot-Server-Patches/InventoryCloseEvent-Reason-API.patch @@ -114,7 +114,7 @@ index a61815c794..5ae0927c14 100644 PlayerQuitEvent playerQuitEvent = new PlayerQuitEvent(cserver.getPlayer(entityplayer), "\u00A7e" + entityplayer.getName() + " left the game"); cserver.getPluginManager().callEvent(playerQuitEvent); diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index da391e945c..c5b4218b44 100644 +index 60f936f2e5..7c1a748c9b 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 { diff --git a/Spigot-Server-Patches/Limit-lightning-strike-effect-distance.patch b/Spigot-Server-Patches/Limit-lightning-strike-effect-distance.patch index e5adeb3516..ed9b319bbb 100644 --- a/Spigot-Server-Patches/Limit-lightning-strike-effect-distance.patch +++ b/Spigot-Server-Patches/Limit-lightning-strike-effect-distance.patch @@ -69,7 +69,7 @@ index 7c518983a9..bdb534deb4 100644 --this.lifeTicks; diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index 09176e6040..43565dd92c 100644 +index ad779650ed..a75034079b 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 { diff --git a/Spigot-Server-Patches/Load-Chunks-for-Login-Asynchronously.patch b/Spigot-Server-Patches/Load-Chunks-for-Login-Asynchronously.patch index cb860e80ca..e9e1c226b9 100644 --- a/Spigot-Server-Patches/Load-Chunks-for-Login-Asynchronously.patch +++ b/Spigot-Server-Patches/Load-Chunks-for-Login-Asynchronously.patch @@ -18,7 +18,7 @@ index 324fd07bce..01330045c0 100644 public void setPositionRotation(BlockPosition blockposition, float f, float f1) { diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java -index a48e113b53..0f9bca8b8b 100644 +index 45df816980..48bbaec4b6 100644 --- a/src/main/java/net/minecraft/server/EntityPlayer.java +++ b/src/main/java/net/minecraft/server/EntityPlayer.java @@ -0,0 +0,0 @@ public class EntityPlayer extends EntityHuman implements ICrafting { diff --git a/Spigot-Server-Patches/MC-Utils.patch b/Spigot-Server-Patches/MC-Utils.patch index 286cd8b274..bcfa03dcc1 100644 --- a/Spigot-Server-Patches/MC-Utils.patch +++ b/Spigot-Server-Patches/MC-Utils.patch @@ -248,7 +248,7 @@ index 0000000000..59868f37d1 +} diff --git a/src/main/java/com/destroystokyo/paper/util/map/QueuedChangesMapLong2Object.java b/src/main/java/com/destroystokyo/paper/util/map/QueuedChangesMapLong2Object.java new file mode 100644 -index 0000000000..07685b6bd5 +index 0000000000..7bab31a312 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/util/map/QueuedChangesMapLong2Object.java @@ -0,0 +0,0 @@ @@ -300,10 +300,18 @@ index 0000000000..07685b6bd5 + return this.updatingMap.get(k); + } + ++ public boolean updatingContainsKey(final long k) { ++ return this.updatingMap.containsKey(k); ++ } ++ + public V getVisible(final long k) { + return this.visibleMap.get(k); + } + ++ public boolean visibleContainsKey(final long k) { ++ return this.visibleMap.containsKey(k); ++ } ++ + public V getVisibleAsync(final long k) { + long readlock; + V ret = null; @@ -326,6 +334,28 @@ index 0000000000..07685b6bd5 + return ret; + } + ++ public boolean visibleContainsKeyAsync(final long k) { ++ long readlock; ++ boolean ret = false; ++ ++ do { ++ readlock = this.updatingMapSeqLock.acquireRead(); ++ ++ try { ++ ret = this.visibleMap.containsKey(k); ++ } catch (final Throwable thr) { ++ if (thr instanceof ThreadDeath) { ++ throw (ThreadDeath)thr; ++ } ++ // ignore... ++ continue; ++ } ++ ++ } while (!this.updatingMapSeqLock.tryReleaseRead(readlock)); ++ ++ return ret; ++ } ++ + public Long2ObjectLinkedOpenHashMap getVisibleMap() { + return this.visibleMap; + } @@ -1065,7 +1095,7 @@ index 0000000000..c3b936f54b +} diff --git a/src/main/java/com/destroystokyo/paper/util/misc/AreaMap.java b/src/main/java/com/destroystokyo/paper/util/misc/AreaMap.java new file mode 100644 -index 0000000000..f625da9f09 +index 0000000000..c71ed11834 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/util/misc/AreaMap.java @@ -0,0 +0,0 @@ @@ -1148,27 +1178,57 @@ index 0000000000..f625da9f09 + return this.areaMap.size(); + } + -+ public final void update(final E object, final int chunkX, final int chunkZ, final int viewDistance) { ++ public final void addOrUpdate(final E object, final int chunkX, final int chunkZ, final int viewDistance) { + final int oldViewDistance = this.objectToViewDistance.put(object, viewDistance); + final long newPos = MCUtil.getCoordinateKey(chunkX, chunkZ); ++ final long oldPos = this.objectToLastCoordinate.put(object, newPos); ++ + if (oldViewDistance == -1) { -+ this.objectToLastCoordinate.put(object, newPos); + this.addObject(object, chunkX, chunkZ, Integer.MIN_VALUE, Integer.MIN_VALUE, viewDistance); + this.addObjectCallback(object, chunkX, chunkZ, viewDistance); + } else { -+ final long oldPos = this.objectToLastCoordinate.put(object, newPos); + this.updateObject(object, oldPos, newPos, oldViewDistance, viewDistance); + this.updateObjectCallback(object, oldPos, newPos, oldViewDistance, viewDistance); + } + //this.validate(object, viewDistance); + } + -+ // called after the distance map updates -+ protected void addObjectCallback(final E object, final int chunkX, final int chunkZ, final int viewDistance) {} ++ public final boolean update(final E object, final int chunkX, final int chunkZ, final int viewDistance) { ++ final int oldViewDistance = this.objectToViewDistance.replace(object, viewDistance); ++ if (oldViewDistance == -1) { ++ return false; ++ } else { ++ final long newPos = MCUtil.getCoordinateKey(chunkX, chunkZ); ++ final long oldPos = this.objectToLastCoordinate.put(object, newPos); ++ this.updateObject(object, oldPos, newPos, oldViewDistance, viewDistance); ++ this.updateObjectCallback(object, oldPos, newPos, oldViewDistance, viewDistance); ++ } ++ //this.validate(object, viewDistance); ++ return true; ++ } + + // called after the distance map updates + protected void updateObjectCallback(final E Object, final long oldPosition, final long newPosition, final int oldViewDistance, final int newViewDistance) {} + ++ public final boolean add(final E object, final int chunkX, final int chunkZ, final int viewDistance) { ++ final int oldViewDistance = this.objectToViewDistance.putIfAbsent(object, viewDistance); ++ if (oldViewDistance != -1) { ++ return false; ++ } ++ ++ final long newPos = MCUtil.getCoordinateKey(chunkX, chunkZ); ++ this.objectToLastCoordinate.put(object, newPos); ++ this.addObject(object, chunkX, chunkZ, Integer.MIN_VALUE, Integer.MIN_VALUE, viewDistance); ++ this.addObjectCallback(object, chunkX, chunkZ, viewDistance); ++ ++ //this.validate(object, viewDistance); ++ ++ return true; ++ } ++ ++ // called after the distance map updates ++ protected void addObjectCallback(final E object, final int chunkX, final int chunkZ, final int viewDistance) {} ++ + public final boolean remove(final E object) { + final long position = this.objectToLastCoordinate.removeLong(object); + final int viewDistance = this.objectToViewDistance.removeInt(object); @@ -2015,6 +2075,197 @@ index 0000000000..e51104e65a + } + } +} +diff --git a/src/main/java/com/destroystokyo/paper/util/pooled/PooledObjects.java b/src/main/java/com/destroystokyo/paper/util/pooled/PooledObjects.java +new file mode 100644 +index 0000000000..d4325f1f11 +--- /dev/null ++++ b/src/main/java/com/destroystokyo/paper/util/pooled/PooledObjects.java +@@ -0,0 +0,0 @@ ++package com.destroystokyo.paper.util.pooled; ++ ++import org.apache.commons.lang3.mutable.MutableInt; ++import java.util.ArrayDeque; ++import java.util.concurrent.ThreadLocalRandom; ++import java.util.concurrent.locks.ReentrantLock; ++ ++public final class PooledObjects { ++ ++ public static final PooledObjects POOLED_MUTABLE_INTEGERS = new PooledObjects<>(new PooledObjectHandler() { ++ @Override ++ public MutableInt createNew() { ++ return new MutableInt(); ++ } ++ ++ @Override ++ public void onAcquire(final MutableInt value) {} ++ ++ @Override ++ public void onRelease(final MutableInt value) {} ++ }, 200, -1); ++ ++ private final PooledObjectHandler handler; ++ private final int maxPoolSize; ++ private final int expectingThreads; ++ ++ private final IsolatedPool mainPool; ++ // use these under contention ++ private final IsolatedPool[] contendedPools; ++ ++ public PooledObjects(final PooledObjectHandler handler, final int maxPoolSize, int expectingThreads) { ++ if (handler == null) { ++ throw new NullPointerException("Handler must not be null"); ++ } ++ if (maxPoolSize <= 0) { ++ throw new IllegalArgumentException("Max pool size must be greater-than 0"); ++ } ++ if (expectingThreads <= 0) { ++ expectingThreads = Runtime.getRuntime().availableProcessors(); ++ } ++ ++ this.handler = handler; ++ this.maxPoolSize = maxPoolSize; ++ this.expectingThreads = expectingThreads; ++ this.mainPool = new IsolatedPool<>(handler, maxPoolSize); ++ final IsolatedPool[] contendedPools = new IsolatedPool[2 * expectingThreads]; ++ ++ for (int i = 0; i < contendedPools.length; ++i) { ++ contendedPools[i] = new IsolatedPool<>(handler, Math.max(1, maxPoolSize / 2)); ++ } ++ ++ this.contendedPools = contendedPools; ++ } ++ ++ // Taken from ++ // https://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/ ++ // https://github.com/lemire/Code-used-on-Daniel-Lemire-s-blog/blob/master/2016/06/25/fastrange.c ++ // Original license is public domain ++ public static int fastRandomBounded(final long randomInteger, final long limit) { ++ // randomInteger must be [0, pow(2, 32)) ++ // limit must be [0, pow(2, 32)) ++ return (int)((randomInteger * limit) >>> 32); ++ } ++ ++ public E acquire() { ++ E ret; ++ PooledObjects.IsolatedPool pooled = this.mainPool; ++ int lastIndex = -1; ++ while ((ret = pooled.tryAcquireUncontended()) == null) { ++ int index; ++ while (lastIndex == (index = fastRandomBounded(ThreadLocalRandom.current().nextInt() & 0xFFFFFFFFL, this.contendedPools.length))); ++ lastIndex = index; ++ pooled = this.contendedPools[index]; ++ } ++ ++ return ret; ++ } ++ ++ public void release(final E value) { ++ PooledObjects.IsolatedPool pooled = this.mainPool; ++ int lastIndex = -1; ++ while (!pooled.tryReleaseUncontended(value)) { ++ int index; ++ while (lastIndex == (index = fastRandomBounded(ThreadLocalRandom.current().nextInt() & 0xFFFFFFFFL, this.contendedPools.length))); ++ lastIndex = index; ++ pooled = this.contendedPools[index]; ++ } ++ } ++ ++ /** This object is restricted from interacting with any pool */ ++ static interface PooledObjectHandler { ++ ++ /** ++ * Must return a non-null object ++ */ ++ E createNew(); ++ ++ void onAcquire(final E value); ++ ++ void onRelease(final E value); ++ } ++ ++ protected static class IsolatedPool { ++ ++ protected final PooledObjectHandler handler; ++ ++ // We use arraydeque as it doesn't create garbage per element... ++ protected final ArrayDeque pool; ++ protected final int maxPoolSize; ++ ++ protected final ReentrantLock lock = new ReentrantLock(); ++ ++ public IsolatedPool(final PooledObjectHandler handler, final int maxPoolSize) { ++ this.handler = handler; ++ this.pool = new ArrayDeque<>(); ++ this.maxPoolSize = maxPoolSize; ++ } ++ ++ protected E acquireOrCreateNoLock() { ++ E ret; ++ ++ ret = this.pool.poll(); ++ ++ if (ret == null) { ++ ret = this.handler.createNew(); ++ } ++ this.handler.onAcquire(ret); ++ ++ return ret; ++ } ++ ++ public E tryAcquireUncontended() { ++ if (!this.lock.tryLock()) { ++ return null; ++ } ++ try { ++ return this.acquireOrCreateNoLock(); ++ } finally { ++ this.lock.unlock(); ++ } ++ } ++ ++ public E acquire() { ++ this.lock.lock(); ++ try { ++ return this.acquireOrCreateNoLock(); ++ } finally { ++ this.lock.unlock(); ++ } ++ } ++ ++ protected void releaseNoLock(final E value) { ++ if (this.pool.size() >= this.maxPoolSize) { ++ this.handler.onRelease(value); ++ return; // can't accept, we're at capacity ++ } ++ ++ this.pool.add(value); ++ this.handler.onRelease(value); ++ } ++ ++ public boolean tryReleaseUncontended(final E value) { ++ if (!this.lock.tryLock()) { ++ return false; ++ } ++ ++ try { ++ this.releaseNoLock(value); ++ } finally { ++ this.lock.unlock(); ++ } ++ ++ return true; ++ } ++ ++ public void release(final E value) { ++ this.lock.lock(); ++ try { ++ this.releaseNoLock(value); ++ } finally { ++ this.lock.unlock(); ++ } ++ } ++ } ++} diff --git a/src/main/java/com/destroystokyo/paper/util/set/OptimizedSmallEnumSet.java b/src/main/java/com/destroystokyo/paper/util/set/OptimizedSmallEnumSet.java new file mode 100644 index 0000000000..9df0006c1a @@ -2136,7 +2387,7 @@ index 1cf97cefc9..2040f18349 100644 return this.d.containsKey(iblockstate); } diff --git a/src/main/java/net/minecraft/server/BlockPosition.java b/src/main/java/net/minecraft/server/BlockPosition.java -index c88a62f6b7..5dbd3e60fe 100644 +index c88a62f6b7..f8ac39e1b0 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 implements MinecraftSeriali @@ -2156,6 +2407,14 @@ index c88a62f6b7..5dbd3e60fe 100644 public BlockPosition immutableCopy() { return this; } +@@ -0,0 +0,0 @@ public class BlockPosition extends BaseBlockPosition implements MinecraftSeriali + super(i, j, k); + } + ++ public static BlockPosition.PooledBlockPosition acquire() { return r(); } // Paper - OBFHELPER + public static BlockPosition.PooledBlockPosition r() { + return f(0, 0, 0); + } @@ -0,0 +0,0 @@ public class BlockPosition extends BaseBlockPosition implements MinecraftSeriali return this.d; } @@ -2191,7 +2450,7 @@ index c88a62f6b7..5dbd3e60fe 100644 this.d = i; } diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java -index 55373cae07..c50fe1c245 100644 +index 55373cae07..b39ce329aa 100644 --- a/src/main/java/net/minecraft/server/Chunk.java +++ b/src/main/java/net/minecraft/server/Chunk.java @@ -0,0 +0,0 @@ import org.apache.logging.log4j.Logger; @@ -2256,27 +2515,41 @@ index 55373cae07..c50fe1c245 100644 + if (chunk == null) { + throw new IllegalArgumentException("Chunk must be non-null, neighbour: (" + relativeX + "," + relativeZ + "), chunk: " + this.loc); + } ++ final long before = this.neighbourChunksLoadedBitset; + final int index = getNeighbourIndex(relativeX, relativeZ); + this.loadedNeighbourChunks[index] = chunk; + this.neighbourChunksLoadedBitset |= (1L << index); ++ this.onNeighbourChange(before, this.neighbourChunksLoadedBitset); + } + + public final void setNeighbourUnloaded(final int relativeX, final int relativeZ) { ++ final long before = this.neighbourChunksLoadedBitset; + final int index = getNeighbourIndex(relativeX, relativeZ); + this.loadedNeighbourChunks[index] = null; + this.neighbourChunksLoadedBitset &= ~(1L << index); ++ this.onNeighbourChange(before, this.neighbourChunksLoadedBitset); + } + + public final void resetNeighbours() { ++ final long before = this.neighbourChunksLoadedBitset; + this.neighbourChunksLoadedBitset = 0L; + java.util.Arrays.fill(this.loadedNeighbourChunks, null); ++ this.onNeighbourChange(before, 0L); ++ } ++ ++ protected void onNeighbourChange(final long bitsetBefore, final long bitsetAfter) { ++ + } + + public final boolean areNeighboursLoaded(final int radius) { ++ return Chunk.areNeighboursLoaded(this.neighbourChunksLoadedBitset, radius); ++ } ++ ++ public static boolean areNeighboursLoaded(final long bitset, final int radius) { + // index = relativeX + (relativeZ * (NEIGHBOUR_CACHE_RADIUS * 2 + 1)) + (NEIGHBOUR_CACHE_RADIUS + NEIGHBOUR_CACHE_RADIUS * ((NEIGHBOUR_CACHE_RADIUS * 2 + 1))) + switch (radius) { + case 0: { -+ return this.loadedTicketLevel; ++ return (bitset & (1L << getNeighbourIndex(0, 0))) != 0; + } + case 1: { + long mask = 0L; @@ -2285,7 +2558,7 @@ index 55373cae07..c50fe1c245 100644 + mask |= (1L << getNeighbourIndex(dx, dz)); + } + } -+ return (this.neighbourChunksLoadedBitset & mask) == mask; ++ return (bitset & mask) == mask; + } + case 2: { + long mask = 0L; @@ -2294,7 +2567,7 @@ index 55373cae07..c50fe1c245 100644 + mask |= (1L << getNeighbourIndex(dx, dz)); + } + } -+ return (this.neighbourChunksLoadedBitset & mask) == mask; ++ return (bitset & mask) == mask; + } + case 3: { + long mask = 0L; @@ -2303,7 +2576,7 @@ index 55373cae07..c50fe1c245 100644 + mask |= (1L << getNeighbourIndex(dx, dz)); + } + } -+ return (this.neighbourChunksLoadedBitset & mask) == mask; ++ return (bitset & mask) == mask; + } + + default: @@ -3704,7 +3977,7 @@ index 5c5bf010d0..6e9f402fb0 100644 } diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java -index 7ad30548e2..93d838ec2d 100644 +index 7ad30548e2..b505244516 100644 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { @@ -3715,26 +3988,19 @@ index 7ad30548e2..93d838ec2d 100644 + private final com.destroystokyo.paper.util.misc.PooledLinkedHashSets pooledLinkedPlayerHashSets = new com.destroystokyo.paper.util.misc.PooledLinkedHashSets<>(); + + void addPlayerToDistanceMaps(EntityPlayer player) { -+ this.updateMaps(player); -+ -+ -+ ++ int chunkX = MCUtil.getChunkCoordinate(player.locX()); ++ int chunkZ = MCUtil.getChunkCoordinate(player.locZ()); ++ // Note: players need to be explicitly added to distance maps before they can be updated + } + + void removePlayerFromDistanceMaps(EntityPlayer player) { + -+ -+ -+ + } + + void updateMaps(EntityPlayer player) { + int chunkX = MCUtil.getChunkCoordinate(player.locX()); + int chunkZ = MCUtil.getChunkCoordinate(player.locZ()); -+ -+ -+ -+ ++ // Note: players need to be explicitly added to distance maps before they can be updated + } + + @@ -3743,6 +4009,37 @@ index 7ad30548e2..93d838ec2d 100644 public PlayerChunkMap(WorldServer worldserver, File file, DataFixer datafixer, DefinedStructureManager definedstructuremanager, Executor executor, IAsyncTaskHandler iasynctaskhandler, ILightAccess ilightaccess, ChunkGenerator chunkgenerator, WorldLoadListener worldloadlistener, Supplier supplier, int i) { super(new File(worldserver.getWorldProvider().getDimensionManager().a(file), "region"), datafixer); this.visibleChunks = this.updatingChunks.clone(); +@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { + }; + } + ++ // Paper start ++ public final int getEffectiveViewDistance() { ++ // TODO this needs to be checked on update ++ // Mojang currently sets it to +1 of the configured view distance. So subtract one to get the one we really want. ++ return this.viewDistance - 1; ++ } ++ // Paper end ++ + private CompletableFuture, PlayerChunk.Failure>> a(ChunkCoordIntPair chunkcoordintpair, int i, IntFunction intfunction) { + List>> list = Lists.newArrayList(); + int j = chunkcoordintpair.x; +@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { + if (!flag1) { + this.chunkDistanceManager.a(SectionPosition.a((Entity) entityplayer), entityplayer); + } ++ this.addPlayerToDistanceMaps(entityplayer); // Paper - distance maps + } else { + SectionPosition sectionposition = entityplayer.K(); + +@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { + if (!flag2) { + this.chunkDistanceManager.b(sectionposition, entityplayer); + } ++ this.removePlayerFromDistanceMaps(entityplayer); // Paper - distance maps + } + + for (int k = i - this.viewDistance; k <= i + this.viewDistance; ++k) { @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { } } @@ -3961,26 +4258,6 @@ index 2e1eabba14..2a4fa455ff 100644 Fluid fluid = this.getFluid(blockposition); return this.setTypeAndData(blockposition, fluid.getBlockData(), 3 | (flag ? 64 : 0)); -diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index d5014abc9d..8a5ac6f69b 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 { - } - - this.registerEntity(entityplayer); -+ this.getChunkProvider().playerChunkMap.addPlayerToDistanceMaps(entityplayer); // Paper - distance maps - } - - // CraftBukkit start -@@ -0,0 +0,0 @@ public class WorldServer extends World { - EntityPlayer entityplayer = (EntityPlayer) entity; - - this.players.remove(entityplayer); -+ this.getChunkProvider().playerChunkMap.removePlayerFromDistanceMaps(entityplayer); // Paper - distance maps - } - - this.getScoreboard().a(entity); diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java index e181df6f4d..4a9132c701 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java diff --git a/Spigot-Server-Patches/Make-targetSize-more-aggressive-in-the-chunk-unload-.patch b/Spigot-Server-Patches/Make-targetSize-more-aggressive-in-the-chunk-unload-.patch index 4d55e2aa20..85f3e3a9c4 100644 --- a/Spigot-Server-Patches/Make-targetSize-more-aggressive-in-the-chunk-unload-.patch +++ b/Spigot-Server-Patches/Make-targetSize-more-aggressive-in-the-chunk-unload-.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Make targetSize more aggressive in the chunk unload queue diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java -index a79e4cef4a..a851997e5f 100644 +index 6374bf8785..0edba59675 100644 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { diff --git a/Spigot-Server-Patches/Mark-chunk-dirty-anytime-entities-change-to-guarante.patch b/Spigot-Server-Patches/Mark-chunk-dirty-anytime-entities-change-to-guarante.patch index 972f4da6fa..2a6b356bc9 100644 --- a/Spigot-Server-Patches/Mark-chunk-dirty-anytime-entities-change-to-guarante.patch +++ b/Spigot-Server-Patches/Mark-chunk-dirty-anytime-entities-change-to-guarante.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Mark chunk dirty anytime entities change to guarantee it diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java -index e66bbb7ee3..803afed60d 100644 +index 87d68a3e21..6a40dddf46 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 { diff --git a/Spigot-Server-Patches/Mark-entities-as-being-ticked-when-notifying-navigat.patch b/Spigot-Server-Patches/Mark-entities-as-being-ticked-when-notifying-navigat.patch index 4987e84549..2ca06da88f 100644 --- a/Spigot-Server-Patches/Mark-entities-as-being-ticked-when-notifying-navigat.patch +++ b/Spigot-Server-Patches/Mark-entities-as-being-ticked-when-notifying-navigat.patch @@ -5,7 +5,7 @@ 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 6654b91998..e3913952d9 100644 +index 5d1fa08f69..8561f96b9a 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 { diff --git a/Spigot-Server-Patches/Mid-Tick-Chunk-Tasks-Speed-up-processing-of-chunk-lo.patch b/Spigot-Server-Patches/Mid-Tick-Chunk-Tasks-Speed-up-processing-of-chunk-lo.patch index 57ba96eb61..d0b135acd4 100644 --- a/Spigot-Server-Patches/Mid-Tick-Chunk-Tasks-Speed-up-processing-of-chunk-lo.patch +++ b/Spigot-Server-Patches/Mid-Tick-Chunk-Tasks-Speed-up-processing-of-chunk-lo.patch @@ -226,7 +226,7 @@ index 77adc64e30..3c25436f15 100644 // Spigot Start CrashReport crashreport; diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index 532aba2a5d..dc01fb494d 100644 +index 2a7a47c670..9b5f24c262 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 { diff --git a/Spigot-Server-Patches/Optimise-Chunk-getFluid.patch b/Spigot-Server-Patches/Optimise-Chunk-getFluid.patch index fbf74f69e1..4bd593d60e 100644 --- a/Spigot-Server-Patches/Optimise-Chunk-getFluid.patch +++ b/Spigot-Server-Patches/Optimise-Chunk-getFluid.patch @@ -8,7 +8,7 @@ faster on its own, however removing the try catch makes it easier to inline due to code size diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java -index 2e3db1a755..d802acef71 100644 +index 65882f4632..696634ebf5 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 { diff --git a/Spigot-Server-Patches/Optimise-entity-hard-collision-checking.patch b/Spigot-Server-Patches/Optimise-entity-hard-collision-checking.patch index 47b8052dde..ecd69406eb 100644 --- a/Spigot-Server-Patches/Optimise-entity-hard-collision-checking.patch +++ b/Spigot-Server-Patches/Optimise-entity-hard-collision-checking.patch @@ -11,7 +11,7 @@ Less crammed entities are likely to show significantly less benefit. Effectively, this patch optimises crammed entity situations. diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java -index d802acef71..09137d8785 100644 +index 696634ebf5..00dd21205d 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 { @@ -133,7 +133,7 @@ index 0dbe2dce11..324fd07bce 100644 this.id = Entity.entityCount.incrementAndGet(); this.passengers = Lists.newArrayList(); diff --git a/src/main/java/net/minecraft/server/EntityEnderDragon.java b/src/main/java/net/minecraft/server/EntityEnderDragon.java -index af10fc36e0..2887cb14e4 100644 +index 5bf99e0028..aecdaacfc7 100644 --- a/src/main/java/net/minecraft/server/EntityEnderDragon.java +++ b/src/main/java/net/minecraft/server/EntityEnderDragon.java @@ -0,0 +0,0 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster { diff --git a/Spigot-Server-Patches/Optimise-random-block-ticking.patch b/Spigot-Server-Patches/Optimise-random-block-ticking.patch index 2f46e81a5e..6cd1146f67 100644 --- a/Spigot-Server-Patches/Optimise-random-block-ticking.patch +++ b/Spigot-Server-Patches/Optimise-random-block-ticking.patch @@ -99,7 +99,7 @@ index 6d351f0979..a44f65f40d 100644 @Override diff --git a/src/main/java/net/minecraft/server/BlockPosition.java b/src/main/java/net/minecraft/server/BlockPosition.java -index e76528f199..e650a2e48d 100644 +index db7ba12fd4..9010359fbd 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 implements MinecraftSeriali @@ -111,7 +111,7 @@ index e76528f199..e650a2e48d 100644 return this.d(baseblockposition.getX(), baseblockposition.getY(), baseblockposition.getZ()); } diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java -index a23dfeb63d..2e3db1a755 100644 +index 42eede6781..65882f4632 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 { @@ -376,7 +376,7 @@ index 0c23fc89d7..de9f49b884 100644 public boolean isSavingDisabled() { diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index 62fabb7ad5..9a2b4fa7a2 100644 +index c348e3e500..fcbc9f2913 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 { diff --git a/Spigot-Server-Patches/Optimize-PlayerChunkMap-memory-use-for-visibleChunks.patch b/Spigot-Server-Patches/Optimize-PlayerChunkMap-memory-use-for-visibleChunks.patch index f8cfc426e2..353c4f4ba7 100644 --- a/Spigot-Server-Patches/Optimize-PlayerChunkMap-memory-use-for-visibleChunks.patch +++ b/Spigot-Server-Patches/Optimize-PlayerChunkMap-memory-use-for-visibleChunks.patch @@ -76,7 +76,7 @@ index d9941b38ca..71ab65e00f 100644 List allChunks = new ArrayList<>(visibleChunks.values()); List players = world.players; diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java -index 7647b804fa..fb7bbe8744 100644 +index e22ef19534..db5a35598d 100644 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { diff --git a/Spigot-Server-Patches/Optimize-isValidLocation-getType-and-getBlockData-fo.patch b/Spigot-Server-Patches/Optimize-isValidLocation-getType-and-getBlockData-fo.patch index 6e9274bcf2..cdb42b5b02 100644 --- a/Spigot-Server-Patches/Optimize-isValidLocation-getType-and-getBlockData-fo.patch +++ b/Spigot-Server-Patches/Optimize-isValidLocation-getType-and-getBlockData-fo.patch @@ -31,7 +31,7 @@ index a3b5793e48..71089442c1 100644 public BaseBlockPosition(int i, int j, int k) { this.a = i; diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java -index 39e77f8248..7ddf6592f7 100644 +index 8f3eee5ea8..4b162a768e 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 { diff --git a/Spigot-Server-Patches/Option-to-remove-corrupt-tile-entities.patch b/Spigot-Server-Patches/Option-to-remove-corrupt-tile-entities.patch index edd5a7d146..1be70814cc 100644 --- a/Spigot-Server-Patches/Option-to-remove-corrupt-tile-entities.patch +++ b/Spigot-Server-Patches/Option-to-remove-corrupt-tile-entities.patch @@ -19,7 +19,7 @@ index 8cf3076f4e..721eceeffc 100644 + } } diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java -index d1761ff3c4..e66bbb7ee3 100644 +index 6694d0e36c..87d68a3e21 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 { diff --git a/Spigot-Server-Patches/Per-Player-View-Distance-API-placeholders.patch b/Spigot-Server-Patches/Per-Player-View-Distance-API-placeholders.patch index d1a38d0e15..57f074f5c7 100644 --- a/Spigot-Server-Patches/Per-Player-View-Distance-API-placeholders.patch +++ b/Spigot-Server-Patches/Per-Player-View-Distance-API-placeholders.patch @@ -7,7 +7,7 @@ I hope to look at this more in-depth soon. It appears doable. However this should not block the update. diff --git a/src/main/java/net/minecraft/server/EntityEnderDragon.java b/src/main/java/net/minecraft/server/EntityEnderDragon.java -index 6a4ccaeb0f..af10fc36e0 100644 +index 6a4ccaeb0f..5bf99e0028 100644 --- a/src/main/java/net/minecraft/server/EntityEnderDragon.java +++ b/src/main/java/net/minecraft/server/EntityEnderDragon.java @@ -0,0 +0,0 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster { @@ -15,7 +15,7 @@ index 6a4ccaeb0f..af10fc36e0 100644 // this.world.b(1028, new BlockPosition(this), 0); // Paper start - //int viewDistance = ((WorldServer) this.world).spigotConfig.viewDistance * 16; // Paper - updated to use worlds actual view distance incase we have to uncomment this due to removal of player view distance API -+ int viewDistance = ((WorldServer) this.world).spigotConfig.viewDistance * 16; // Paper - updated to use worlds actual view distance incase we have to uncomment this due to removal of player view distance API ++ int viewDistance = this.world.getWorld().getViewDistance() * 16; // Paper - updated to use worlds actual view distance incase we have to uncomment this due to removal of player view distance API for (EntityPlayer player : ((WorldServer)world).getPlayers()) { - final int viewDistance = player.getViewDistance(); // TODO apply view distance api patch + //final int viewDistance = player.getViewDistance(); // TODO apply view distance api patch @@ -23,7 +23,7 @@ index 6a4ccaeb0f..af10fc36e0 100644 double deltaX = this.locX() - player.locX(); double deltaZ = this.locZ() - player.locZ(); diff --git a/src/main/java/net/minecraft/server/EntityWither.java b/src/main/java/net/minecraft/server/EntityWither.java -index 2e95069c19..8977c3516b 100644 +index 2e95069c19..2f466af4d5 100644 --- a/src/main/java/net/minecraft/server/EntityWither.java +++ b/src/main/java/net/minecraft/server/EntityWither.java @@ -0,0 +0,0 @@ public class EntityWither extends EntityMonster implements IRangedEntity { @@ -31,7 +31,7 @@ index 2e95069c19..8977c3516b 100644 // this.world.b(1023, new BlockPosition(this), 0); // Paper start - //int viewDistance = ((WorldServer) this.world).spigotConfig.viewDistance * 16; // Paper - updated to use worlds actual view distance incase we have to uncomment this due to removal of player view distance API -+ int viewDistance = ((WorldServer) this.world).spigotConfig.viewDistance * 16; // Paper - updated to use worlds actual view distance incase we have to uncomment this due to removal of player view distance API ++ int viewDistance = this.world.getWorld().getViewDistance() * 16; // Paper - updated to use worlds actual view distance incase we have to uncomment this due to removal of player view distance API for (EntityPlayer player : ((WorldServer)world).getPlayers()) { - final int viewDistance = player.getViewDistance(); // TODO apply view distance api patch + //final int viewDistance = player.getViewDistance(); // TODO apply view distance api patch @@ -39,7 +39,7 @@ index 2e95069c19..8977c3516b 100644 double deltaX = this.locX() - player.locX(); double deltaZ = this.locZ() - player.locZ(); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 6e3bcfe2cd..e76f2b9c7f 100644 +index 6e3bcfe2cd..6672feaf51 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @@ -49,12 +49,12 @@ index 6e3bcfe2cd..e76f2b9c7f 100644 + + @Override + public int getViewDistance() { -+ throw new NotImplementedException("Per-Player View Distance APIs need further understanding to properly implement"); // TODO ++ throw new NotImplementedException("Per-Player View Distance APIs need further understanding to properly implement (There are per world view distances though!)"); // TODO + } + + @Override + public void setViewDistance(int viewDistance) { -+ throw new NotImplementedException("Per-Player View Distance APIs need further understanding to properly implement"); // TODO ++ throw new NotImplementedException("Per-Player View Distance APIs need further understanding to properly implement (There are per world view distances though!)"); // TODO + } // Paper end diff --git a/Spigot-Server-Patches/Pillager-patrol-spawn-settings-and-per-player-option.patch b/Spigot-Server-Patches/Pillager-patrol-spawn-settings-and-per-player-option.patch index 4d8ee35e33..027121ff5c 100644 --- a/Spigot-Server-Patches/Pillager-patrol-spawn-settings-and-per-player-option.patch +++ b/Spigot-Server-Patches/Pillager-patrol-spawn-settings-and-per-player-option.patch @@ -10,7 +10,7 @@ When not per player it will use the Vanilla mechanic of one delay per world and the world age for the start day. diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -index e93176d8f2..659a011e97 100644 +index 7ca67a4aa5..803be76772 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 { @@ -36,7 +36,7 @@ index e93176d8f2..659a011e97 100644 private void entitiesTargetWithFollowRange() { entitiesTargetWithFollowRange = getBoolean("entities-target-with-follow-range", entitiesTargetWithFollowRange); diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java -index 9da6ed85fa..c6474aa0f8 100644 +index cf837bdb3b..900631ebe0 100644 --- a/src/main/java/net/minecraft/server/EntityPlayer.java +++ b/src/main/java/net/minecraft/server/EntityPlayer.java @@ -0,0 +0,0 @@ public class EntityPlayer extends EntityHuman implements ICrafting { diff --git a/Spigot-Server-Patches/PlayerNaturallySpawnCreaturesEvent.patch b/Spigot-Server-Patches/PlayerNaturallySpawnCreaturesEvent.patch index b9367ca429..a56cf2dd60 100644 --- a/Spigot-Server-Patches/PlayerNaturallySpawnCreaturesEvent.patch +++ b/Spigot-Server-Patches/PlayerNaturallySpawnCreaturesEvent.patch @@ -48,7 +48,7 @@ index bf32997c42..88692d9eae 100644 public final com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet cachedSingleHashSet; // Paper diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java -index a851997e5f..175734b50c 100644 +index 0edba59675..7804cc0f6a 100644 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { diff --git a/Spigot-Server-Patches/Prevent-Double-PlayerChunkMap-adds-crashing-server.patch b/Spigot-Server-Patches/Prevent-Double-PlayerChunkMap-adds-crashing-server.patch index 6e57661934..3da3146acf 100644 --- a/Spigot-Server-Patches/Prevent-Double-PlayerChunkMap-adds-crashing-server.patch +++ b/Spigot-Server-Patches/Prevent-Double-PlayerChunkMap-adds-crashing-server.patch @@ -7,7 +7,7 @@ Suspected case would be around the technique used in .stopRiding Stack will identify any causer of this and warn instead of crashing. diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java -index 8f477767b9..7647b804fa 100644 +index 73bfebb837..e22ef19534 100644 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { @@ -26,7 +26,7 @@ index 8f477767b9..7647b804fa 100644 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 3f8f40018d..532aba2a5d 100644 +index 9fbe8fa1b2..2a7a47c670 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 { diff --git a/Spigot-Server-Patches/Prevent-Saving-Bad-entities-to-chunks.patch b/Spigot-Server-Patches/Prevent-Saving-Bad-entities-to-chunks.patch index fd2f260bb7..e53572254d 100644 --- a/Spigot-Server-Patches/Prevent-Saving-Bad-entities-to-chunks.patch +++ b/Spigot-Server-Patches/Prevent-Saving-Bad-entities-to-chunks.patch @@ -80,7 +80,7 @@ index 13d99de2cd..f54572773c 100644 public static ChunkStatus.Type a(@Nullable NBTTagCompound nbttagcompound) { if (nbttagcompound != null) { diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index 6ce7f77a5e..87762b1725 100644 +index 02d9c754b1..d1424325d5 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 { diff --git a/Spigot-Server-Patches/Prevent-opening-inventories-when-frozen.patch b/Spigot-Server-Patches/Prevent-opening-inventories-when-frozen.patch index 7a9bad3b49..4e37ab2758 100644 --- a/Spigot-Server-Patches/Prevent-opening-inventories-when-frozen.patch +++ b/Spigot-Server-Patches/Prevent-opening-inventories-when-frozen.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Prevent opening inventories when frozen diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java -index 50886c1374..0c0224d1eb 100644 +index d51af68a92..f453ccdb02 100644 --- a/src/main/java/net/minecraft/server/EntityPlayer.java +++ b/src/main/java/net/minecraft/server/EntityPlayer.java @@ -0,0 +0,0 @@ public class EntityPlayer extends EntityHuman implements ICrafting { diff --git a/Spigot-Server-Patches/Re-add-vanilla-entity-warnings-for-duplicates.patch b/Spigot-Server-Patches/Re-add-vanilla-entity-warnings-for-duplicates.patch index e7d8805dbc..1fc9e4828b 100644 --- a/Spigot-Server-Patches/Re-add-vanilla-entity-warnings-for-duplicates.patch +++ b/Spigot-Server-Patches/Re-add-vanilla-entity-warnings-for-duplicates.patch @@ -8,7 +8,7 @@ These are a critical sign that somethin went wrong, and you've lost some data... We should kind of know about these things you know. diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index c5b4218b44..4cbf390ce0 100644 +index 7c1a748c9b..25e2a6580a 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 { diff --git a/Spigot-Server-Patches/Reduce-entity-tracker-updates-on-move.patch b/Spigot-Server-Patches/Reduce-entity-tracker-updates-on-move.patch deleted file mode 100644 index a661ce3190..0000000000 --- a/Spigot-Server-Patches/Reduce-entity-tracker-updates-on-move.patch +++ /dev/null @@ -1,211 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: froobynooby -Date: Thu, 20 Feb 2020 15:50:49 +0930 -Subject: [PATCH] Reduce entity tracker updates on move - -With this patch, for each player we keep track of a set of -entities that the player is tracking. This is used to split -the entity tracker update logic in the movePlayer method in -PlayerChunkMap in to two parts: -* Full update: Run through all entity trackers and update them -* Partial update: Run through all entity trackers for entities -the player is already tracking and update them - -Partial updates will always take less time than full updates, -usually by a considerable amount if players and entities are -spread out over the map. Assuming they are evenly spread, -and given there are x many players, it would be expected to -take 1/x the time of a full update. - -Full updates are only run if the following conditions are met: -* It has been 20 ticks since the last full update -* The player has moved over set distance since the last full -update (distance is configurable) - -The motivation for the first condition is that the client -sends the server its position once a second, which calls -movePlayer, so at a minimum we want to be sending the player -an updated set of entities it can see every second. - -The motivation for the second condition is that looping -through every entity in world to check if it is now within -the tracking range after the player has moved 0.1 blocks is -largely unnecessary. Checking only after the player has moved -1 or 2 blocks is far better for performance, and very unlikely -to give any noticeable side effects. - -In testing, this has reduced the time taken for movement -packet processing by up to 4x. Packet processing for movement -packets often show up as a major contributor to TPS loss in -servers with large player counts - -diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java -index 7ca67a4aa5..e93176d8f2 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 { - private void zombieVillagerInfectionChance() { - zombieVillagerInfectionChance = getDouble("zombie-villager-infection-chance", zombieVillagerInfectionChance); - } -+ -+ public double trackerUpdateDistance = 1; -+ private void trackerUpdateDistance() { -+ trackerUpdateDistance = getDouble("tracker-update-distance", trackerUpdateDistance); -+ } - } -diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java -index cf837bdb3b..9da6ed85fa 100644 ---- a/src/main/java/net/minecraft/server/EntityPlayer.java -+++ b/src/main/java/net/minecraft/server/EntityPlayer.java -@@ -0,0 +0,0 @@ public class EntityPlayer extends EntityHuman implements ICrafting { - public final int[] mobCounts = new int[ENUMCREATURETYPE_TOTAL_ENUMS]; // Paper - public final com.destroystokyo.paper.util.PooledHashSets.PooledObjectLinkedOpenHashSet cachedSingleMobDistanceMap; - // Paper end -+ // Paper start - Reduce entity tracker updates on move -+ public Vec3D lastTrackedPosition = new Vec3D(0, 0, 0); -+ public long lastTrackedTick; -+ // Paper end - - // CraftBukkit start - public String displayName; -diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java -index 043ba702d7..8f477767b9 100644 ---- a/src/main/java/net/minecraft/server/PlayerChunkMap.java -+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java -@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { - } - - -+ // Paper end -+ -+ // Paper start - Reduce entity tracker updates on move -+ private double trackerUpdateDistanceSquared; -+ private final Int2ObjectMap> playerTrackedEntities = new Int2ObjectOpenHashMap<>(); -+ private final Int2ObjectMap> playerTrackedEntitiesRemoveQueue = new Int2ObjectOpenHashMap<>(); -+ -+ void flushRemoveQueue(EntityPlayer entityplayer) { -+ Queue removeQueue = getPlayerTrackedEntityMapRemoveQueue(entityplayer.getId()); -+ Int2ObjectMap entityMap = getPlayerTrackedEntityMap(entityplayer.getId()); -+ for (Integer id = removeQueue.poll(); id != null; id = removeQueue.poll()) { -+ entityMap.remove(id); -+ } -+ } -+ -+ void flushRemoveQueues() { -+ for (Int2ObjectMap.Entry> entry : playerTrackedEntitiesRemoveQueue.int2ObjectEntrySet()) { -+ Int2ObjectMap entityMap = getPlayerTrackedEntityMap(entry.getKey()); -+ Queue removeQueue = entry.getValue(); -+ for (Integer id = removeQueue.poll(); id != null; id = removeQueue.poll()) { -+ entityMap.remove(id); -+ } -+ } -+ } -+ -+ Int2ObjectMap getPlayerTrackedEntityMap(int id) { -+ return playerTrackedEntities.computeIfAbsent(id, i -> new Int2ObjectOpenHashMap<>()); -+ } -+ -+ Queue getPlayerTrackedEntityMapRemoveQueue(int id) { -+ return playerTrackedEntitiesRemoveQueue.computeIfAbsent(id, i -> new java.util.ArrayDeque<>()); -+ } -+ - // Paper end - - public PlayerChunkMap(WorldServer worldserver, File file, DataFixer datafixer, DefinedStructureManager definedstructuremanager, Executor executor, IAsyncTaskHandler iasynctaskhandler, ILightAccess ilightaccess, ChunkGenerator chunkgenerator, WorldLoadListener worldloadlistener, Supplier supplier, int i) { -@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { - this.m = new VillagePlace(new File(this.w, "poi"), datafixer, this.world); // Paper - this.setViewDistance(i); - this.playerMobDistanceMap = this.world.paperConfig.perPlayerMobSpawns ? new com.destroystokyo.paper.util.PlayerMobDistanceMap() : null; // Paper -+ this.trackerUpdateDistanceSquared = Math.pow(this.world.paperConfig.trackerUpdateDistance, 2); // Paper - } - - public void updatePlayerMobTypeMap(Entity entity) { -@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { - } - - public void movePlayer(EntityPlayer entityplayer) { -- ObjectIterator objectiterator = this.trackedEntities.values().iterator(); -+ // Paper start -+ // ObjectIterator objectiterator = this.trackedEntities.values().iterator(); -+ ObjectIterator objectiterator; - -+ if (MinecraftServer.currentTick - entityplayer.lastTrackedTick >= 20 -+ || entityplayer.lastTrackedPosition.distanceSquared(entityplayer.getPositionVector()) >= trackerUpdateDistanceSquared) { -+ entityplayer.lastTrackedPosition = entityplayer.getPositionVector(); -+ entityplayer.lastTrackedTick = MinecraftServer.currentTick; -+ objectiterator = this.trackedEntities.values().iterator(); // Update all entity trackers -+ } else { -+ objectiterator = getPlayerTrackedEntityMap(entityplayer.getId()).values().iterator(); // Only update entity trackers for already tracked entities -+ } -+ // Paper end - while (objectiterator.hasNext()) { - PlayerChunkMap.EntityTracker playerchunkmap_entitytracker = (PlayerChunkMap.EntityTracker) objectiterator.next(); - -@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { - playerchunkmap_entitytracker.updatePlayer(entityplayer); - } - } -+ flushRemoveQueues(); // Paper - - int i = MathHelper.floor(entityplayer.locX()) >> 4; - int j = MathHelper.floor(entityplayer.locZ()) >> 4; -@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { - - playerchunkmap_entitytracker.clear(entityplayer); - } -+ // Paper start -+ playerTrackedEntities.remove(entityplayer.getId()); -+ playerTrackedEntitiesRemoveQueue.remove(entityplayer.getId()); -+ // Paper end - } - - PlayerChunkMap.EntityTracker playerchunkmap_entitytracker1 = (PlayerChunkMap.EntityTracker) this.trackedEntities.remove(entity.getId()); - - if (playerchunkmap_entitytracker1 != null) { - playerchunkmap_entitytracker1.a(); -+ // Paper start -+ for (EntityPlayer player : playerchunkmap_entitytracker1.trackedPlayers) { -+ getPlayerTrackedEntityMap(player.getId()).remove(playerchunkmap_entitytracker1.tracker.getId()); -+ } -+ // Paper end - } - entity.tracker = null; // Paper - We're no longer tracked - } -@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { - } - world.timings.tracker2.stopTiming(); // Paper - } -- -+ flushRemoveQueues(); // Paper - - } - -@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { - } - } - } -+ flushRemoveQueue(entityplayer); // Paper - - Iterator iterator; - Entity entity1; -@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { - org.spigotmc.AsyncCatcher.catchOp("player tracker clear"); // Spigot - if (this.trackedPlayers.remove(entityplayer)) { - this.trackerEntry.a(entityplayer); -+ getPlayerTrackedEntityMap(entityplayer.getId()).remove(this.tracker.getId()); // Paper - } - - } -@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { - - if (flag1 && this.trackedPlayerMap.putIfAbsent(entityplayer, true) == null) { // Paper - this.trackerEntry.b(entityplayer); -+ getPlayerTrackedEntityMap(entityplayer.getId()).put(this.tracker.getId(), this); // Paper - } - } else if (this.trackedPlayers.remove(entityplayer)) { - this.trackerEntry.a(entityplayer); -+ getPlayerTrackedEntityMapRemoveQueue(entityplayer.getId()).add(this.tracker.getId()); // Paper - } - - } --- \ No newline at end of file diff --git a/Spigot-Server-Patches/Remove-invalid-mob-spawner-tile-entities.patch b/Spigot-Server-Patches/Remove-invalid-mob-spawner-tile-entities.patch index a3f84d6ebc..9c526cc737 100644 --- a/Spigot-Server-Patches/Remove-invalid-mob-spawner-tile-entities.patch +++ b/Spigot-Server-Patches/Remove-invalid-mob-spawner-tile-entities.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Remove invalid mob spawner tile entities diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java -index 4cd353b253..56d740fcad 100644 +index 352bb787fd..687e609cab 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 { diff --git a/Spigot-Server-Patches/Remove-unused-World-Tile-Entity-List.patch b/Spigot-Server-Patches/Remove-unused-World-Tile-Entity-List.patch index 470dc2280e..b6c57f1d4b 100644 --- a/Spigot-Server-Patches/Remove-unused-World-Tile-Entity-List.patch +++ b/Spigot-Server-Patches/Remove-unused-World-Tile-Entity-List.patch @@ -67,7 +67,7 @@ index aaedbaf4d7..0e8d31babd 100644 } diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index fd42f34004..6f66c38650 100644 +index f8d1cb0231..f46da0e8a0 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 { diff --git a/Spigot-Server-Patches/Send-absolute-position-the-first-time-an-entity-is-s.patch b/Spigot-Server-Patches/Send-absolute-position-the-first-time-an-entity-is-s.patch index 4067113971..d5afdae0b5 100644 --- a/Spigot-Server-Patches/Send-absolute-position-the-first-time-an-entity-is-s.patch +++ b/Spigot-Server-Patches/Send-absolute-position-the-first-time-an-entity-is-s.patch @@ -77,7 +77,7 @@ index a75e0ec54e..a13fd9b340 100644 this.c(); diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java -index 5e31b65e16..d49f456f73 100644 +index 65134c8777..eece2f689c 100644 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { 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 19e12df38d..725fd67737 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 @@ -46,7 +46,7 @@ index 5ae0927c14..6b67201852 100644 double d5 = d1 - entityplayer.locY(); double d6 = d2 - entityplayer.locZ(); diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index 8d292604c3..09176e6040 100644 +index f071b61195..ad779650ed 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 { diff --git a/Spigot-Server-Patches/Speedup-BlockPos-by-fixing-inlining.patch b/Spigot-Server-Patches/Speedup-BlockPos-by-fixing-inlining.patch index ed345fbe80..e89475fb0e 100644 --- a/Spigot-Server-Patches/Speedup-BlockPos-by-fixing-inlining.patch +++ b/Spigot-Server-Patches/Speedup-BlockPos-by-fixing-inlining.patch @@ -110,7 +110,7 @@ index 71089442c1..c439a8d019 100644 return (int) (f + f1 + f2); } diff --git a/src/main/java/net/minecraft/server/BlockPosition.java b/src/main/java/net/minecraft/server/BlockPosition.java -index 5dbd3e60fe..e9ea232a78 100644 +index f8ac39e1b0..0ab2b23440 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 implements MinecraftSeriali diff --git a/Spigot-Server-Patches/Store-counts-for-each-Entity-Block-Entity-Type.patch b/Spigot-Server-Patches/Store-counts-for-each-Entity-Block-Entity-Type.patch index 436c1516eb..27926f2a0c 100644 --- a/Spigot-Server-Patches/Store-counts-for-each-Entity-Block-Entity-Type.patch +++ b/Spigot-Server-Patches/Store-counts-for-each-Entity-Block-Entity-Type.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Store counts for each Entity/Block Entity Type Opens door for future patches to optimize performance diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java -index 061384b012..2b6fe2e01d 100644 +index 4d7dc71474..a144f4ef56 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 { diff --git a/Spigot-Server-Patches/Store-reference-to-current-Chunk-for-Entity-and-Bloc.patch b/Spigot-Server-Patches/Store-reference-to-current-Chunk-for-Entity-and-Bloc.patch index f7cd3d16cc..8758fbf957 100644 --- a/Spigot-Server-Patches/Store-reference-to-current-Chunk-for-Entity-and-Bloc.patch +++ b/Spigot-Server-Patches/Store-reference-to-current-Chunk-for-Entity-and-Bloc.patch @@ -8,7 +8,7 @@ This enables us a fast reference to the entities current chunk instead of having to look it up by hashmap lookups. diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java -index c50fe1c245..061384b012 100644 +index b39ce329aa..4d7dc71474 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 { diff --git a/Spigot-Server-Patches/Timings-v2.patch b/Spigot-Server-Patches/Timings-v2.patch index b25fbf65fe..b46ce6cb5e 100644 --- a/Spigot-Server-Patches/Timings-v2.patch +++ b/Spigot-Server-Patches/Timings-v2.patch @@ -343,7 +343,7 @@ index cd72a9c845..5de881371a 100644 private final float frictionFactor; private final float f; diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java -index 2b6fe2e01d..4cd353b253 100644 +index a144f4ef56..352bb787fd 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 { @@ -934,7 +934,7 @@ index b4a0bd7951..67bdd57747 100644 this.methodProfiler.exit(); } diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java -index 93d838ec2d..5e31b65e16 100644 +index b505244516..65134c8777 100644 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java @@ -0,0 +0,0 @@ @@ -1260,7 +1260,7 @@ index 2a4fa455ff..f572c5f227 100644 CrashReport crashreport = CrashReport.a(throwable, "Ticking entity"); CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Entity being ticked"); diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index 8a5ac6f69b..6810d49b17 100644 +index d5014abc9d..38a71bca2f 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java @@ -0,0 +0,0 @@ diff --git a/Spigot-Server-Patches/Tracking-Range-Improvements.patch b/Spigot-Server-Patches/Tracking-Range-Improvements.patch index a1d3ce7bc0..e77fe1758e 100644 --- a/Spigot-Server-Patches/Tracking-Range-Improvements.patch +++ b/Spigot-Server-Patches/Tracking-Range-Improvements.patch @@ -8,7 +8,7 @@ Sets tracking range of watermobs to animals instead of misc and simplifies code Also ignores Enderdragon, defaulting it to Mojang's setting diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java -index a7b981f299..043ba702d7 100644 +index 0fd1d6b3e6..73bfebb837 100644 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { diff --git a/Spigot-Server-Patches/Use-ChunkStatus-cache-when-saving-protochunks.patch b/Spigot-Server-Patches/Use-ChunkStatus-cache-when-saving-protochunks.patch index 28a3890846..f8a9c5be0d 100644 --- a/Spigot-Server-Patches/Use-ChunkStatus-cache-when-saving-protochunks.patch +++ b/Spigot-Server-Patches/Use-ChunkStatus-cache-when-saving-protochunks.patch @@ -7,7 +7,7 @@ The cache should contain the chunk status when saving. If not it will load it. diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java -index 405f57874e..c9c25cdb8e 100644 +index 1d517fd1ae..9171785ad5 100644 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { diff --git a/Spigot-Server-Patches/Use-distance-map-to-optimise-entity-tracker.patch b/Spigot-Server-Patches/Use-distance-map-to-optimise-entity-tracker.patch new file mode 100644 index 0000000000..10947d2784 --- /dev/null +++ b/Spigot-Server-Patches/Use-distance-map-to-optimise-entity-tracker.patch @@ -0,0 +1,378 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Spottedleaf +Date: Tue, 5 May 2020 20:18:05 -0700 +Subject: [PATCH] Use distance map to optimise entity tracker + +Use the distance map to find candidate players for tracking. + +diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java +index 14ba037c1d..8820e4b650 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 + } + // Paper end + ++ // Paper start - optimise entity tracking ++ final org.spigotmc.TrackingRange.TrackingRangeType trackingRangeType = org.spigotmc.TrackingRange.getTrackingRangeType(this); ++ ++ boolean isLegacyTrackingEntity = false; ++ ++ public final void setLegacyTrackingEntity(final boolean isLegacyTrackingEntity) { ++ this.isLegacyTrackingEntity = isLegacyTrackingEntity; ++ } ++ ++ final com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet getPlayersInTrackRange() { ++ return ((WorldServer)this.world).getChunkProvider().playerChunkMap.playerEntityTrackerTrackMaps[this.trackingRangeType.ordinal()] ++ .getObjectsInRange(MCUtil.getCoordinateKey(this)); ++ } ++ // Paper end - optimise entity tracking ++ + public Entity(EntityTypes entitytypes, World world) { + this.id = Entity.entityCount.incrementAndGet(); + this.passengers = Lists.newArrayList(); +diff --git a/src/main/java/net/minecraft/server/EntityTrackerEntry.java b/src/main/java/net/minecraft/server/EntityTrackerEntry.java +index 3a88c9a670..6d3b34ead9 100644 +--- a/src/main/java/net/minecraft/server/EntityTrackerEntry.java ++++ b/src/main/java/net/minecraft/server/EntityTrackerEntry.java +@@ -0,0 +0,0 @@ public class EntityTrackerEntry { + this.r = entity.onGround; + } + ++ public final void tick() { this.a(); } // Paper - OBFHELPER + public void a() { + List list = this.tracker.getPassengers(); + +diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java +index e08a3bd96c..a780cf5b45 100644 +--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java ++++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java +@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { + + // Paper start - distance maps + private final com.destroystokyo.paper.util.misc.PooledLinkedHashSets pooledLinkedPlayerHashSets = new com.destroystokyo.paper.util.misc.PooledLinkedHashSets<>(); ++ // Paper start - use distance map to optimise tracker ++ public static boolean isLegacyTrackingEntity(Entity entity) { ++ return entity.isLegacyTrackingEntity; ++ } ++ ++ // inlined EnumMap, TrackingRange.TrackingRangeType ++ static final org.spigotmc.TrackingRange.TrackingRangeType[] TRACKING_RANGE_TYPES = org.spigotmc.TrackingRange.TrackingRangeType.values(); ++ final com.destroystokyo.paper.util.misc.PlayerAreaMap[] playerEntityTrackerTrackMaps; ++ final int[] entityTrackerTrackRanges; ++ // Paper end - use distance map to optimise tracker + + void addPlayerToDistanceMaps(EntityPlayer player) { + int chunkX = MCUtil.getChunkCoordinate(player.locX()); + int chunkZ = MCUtil.getChunkCoordinate(player.locZ()); + // Note: players need to be explicitly added to distance maps before they can be updated ++ // Paper start - use distance map to optimise entity tracker ++ for (int i = 0, len = TRACKING_RANGE_TYPES.length; i < len; ++i) { ++ com.destroystokyo.paper.util.misc.PlayerAreaMap trackMap = this.playerEntityTrackerTrackMaps[i]; ++ int trackRange = this.entityTrackerTrackRanges[i]; ++ ++ trackMap.add(player, chunkX, chunkZ, Math.min(trackRange, this.getEffectiveViewDistance())); ++ } ++ // Paper end - use distance map to optimise entity tracker + } + + void removePlayerFromDistanceMaps(EntityPlayer player) { +- ++ // Paper start - use distance map to optimise tracker ++ for (int i = 0, len = TRACKING_RANGE_TYPES.length; i < len; ++i) { ++ this.playerEntityTrackerTrackMaps[i].remove(player); ++ } ++ // Paper end - use distance map to optimise tracker + } + + void updateMaps(EntityPlayer player) { + int chunkX = MCUtil.getChunkCoordinate(player.locX()); + int chunkZ = MCUtil.getChunkCoordinate(player.locZ()); + // Note: players need to be explicitly added to distance maps before they can be updated ++ // Paper start - use distance map to optimise entity tracker ++ for (int i = 0, len = TRACKING_RANGE_TYPES.length; i < len; ++i) { ++ com.destroystokyo.paper.util.misc.PlayerAreaMap trackMap = this.playerEntityTrackerTrackMaps[i]; ++ int trackRange = this.entityTrackerTrackRanges[i]; ++ ++ trackMap.update(player, chunkX, chunkZ, Math.min(trackRange, this.getEffectiveViewDistance())); ++ } ++ // Paper end - use distance map to optimise entity tracker + } + + +@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { + this.m = new VillagePlace(new File(this.w, "poi"), datafixer, this.world); // Paper + this.setViewDistance(i); + this.playerMobDistanceMap = this.world.paperConfig.perPlayerMobSpawns ? new com.destroystokyo.paper.util.PlayerMobDistanceMap() : null; // Paper ++ // Paper start - use distance map to optimise entity tracker ++ this.playerEntityTrackerTrackMaps = new com.destroystokyo.paper.util.misc.PlayerAreaMap[TRACKING_RANGE_TYPES.length]; ++ this.entityTrackerTrackRanges = new int[TRACKING_RANGE_TYPES.length]; ++ ++ org.spigotmc.SpigotWorldConfig spigotWorldConfig = this.world.spigotConfig; ++ ++ for (int ordinal = 0, len = TRACKING_RANGE_TYPES.length; ordinal < len; ++ordinal) { ++ org.spigotmc.TrackingRange.TrackingRangeType trackingRangeType = TRACKING_RANGE_TYPES[ordinal]; ++ int configuredSpigotValue; ++ switch (trackingRangeType) { ++ case PLAYER: ++ configuredSpigotValue = spigotWorldConfig.playerTrackingRange; ++ break; ++ case ANIMAL: ++ configuredSpigotValue = spigotWorldConfig.animalTrackingRange; ++ break; ++ case MONSTER: ++ configuredSpigotValue = spigotWorldConfig.monsterTrackingRange; ++ break; ++ case MISC: ++ configuredSpigotValue = spigotWorldConfig.miscTrackingRange; ++ break; ++ case OTHER: ++ configuredSpigotValue = spigotWorldConfig.otherTrackingRange; ++ break; ++ case ENDERDRAGON: ++ configuredSpigotValue = 10 * 16; // default is 10 chunk range // TODO check on update ++ break; ++ default: ++ throw new IllegalStateException("Missing case for enum " + trackingRangeType); ++ } ++ ++ int trackRange = (configuredSpigotValue >>> 4) + ((configuredSpigotValue & 15) != 0 ? 1 : 0); ++ this.entityTrackerTrackRanges[ordinal] = trackRange; ++ ++ this.playerEntityTrackerTrackMaps[ordinal] = new com.destroystokyo.paper.util.misc.PlayerAreaMap(this.pooledLinkedPlayerHashSets); ++ } ++ // Paper end - use distance map to optimise entity tracker + } + + public void updatePlayerMobTypeMap(Entity entity) { +@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { + } + + public void movePlayer(EntityPlayer entityplayer) { +- ObjectIterator objectiterator = this.trackedEntities.values().iterator(); +- +- while (objectiterator.hasNext()) { +- PlayerChunkMap.EntityTracker playerchunkmap_entitytracker = (PlayerChunkMap.EntityTracker) objectiterator.next(); +- +- if (playerchunkmap_entitytracker.tracker == entityplayer) { +- playerchunkmap_entitytracker.track(this.world.getPlayers()); +- } else { +- playerchunkmap_entitytracker.updatePlayer(entityplayer); +- } +- } ++ // Paper - delay this logic for the entity tracker tick, no need to duplicate it + + int i = MathHelper.floor(entityplayer.locX()) >> 4; + int j = MathHelper.floor(entityplayer.locZ()) >> 4; +@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { + + entity.tracker = playerchunkmap_entitytracker; // Paper - Fast access to tracker + this.trackedEntities.put(entity.getId(), playerchunkmap_entitytracker); +- playerchunkmap_entitytracker.track(this.world.getPlayers()); ++ playerchunkmap_entitytracker.updatePlayers(entity.getPlayersInTrackRange()); // Paper - don't search all players + if (entity instanceof EntityPlayer) { + EntityPlayer entityplayer = (EntityPlayer) entity; + +@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { + entity.tracker = null; // Paper - We're no longer tracked + } + ++ // Paper start - optimised tracker ++ private final void processTrackQueue() { ++ this.world.timings.tracker1.startTiming(); ++ try { ++ Entity[] entities = this.world.loadedEntities.getRawData(); ++ for (int i = 0, len = this.world.loadedEntities.size(); i < len; ++i) { ++ Entity tracked = entities[i]; ++ // update tracker entry ++ EntityTracker tracker = this.trackedEntities.get(tracked.getId()); ++ if (tracker == null) { ++ continue; ++ } ++ tracker.updatePlayers(tracked.getPlayersInTrackRange()); ++ } ++ } finally { ++ this.world.timings.tracker1.stopTiming(); ++ } ++ ++ ++ this.world.timings.tracker2.startTiming(); ++ try { ++ Entity[] entities = this.world.loadedEntities.getRawData(); ++ for (int i = 0, len = this.world.loadedEntities.size(); i < len; ++i) { ++ Entity tracked = entities[i]; ++ EntityTracker tracker = this.trackedEntities.get(tracked.getId()); ++ if (tracker != null) { ++ tracker.trackerEntry.tick(); ++ } ++ } ++ } finally { ++ this.world.timings.tracker2.stopTiming(); ++ } ++ } ++ // Paper end - optimised tracker ++ + protected void g() { ++ // Paper start - optimized tracker ++ if (true) { ++ this.processTrackQueue(); ++ return; ++ } ++ // Paper end - optimized tracker + List list = Lists.newArrayList(); + List list1 = this.world.getPlayers(); + +@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { + PacketDebug.a(this.world, chunk.getPos()); + List list = Lists.newArrayList(); + List list1 = Lists.newArrayList(); +- ObjectIterator objectiterator = this.trackedEntities.values().iterator(); ++ // Paper start - optimise entity tracker ++ // use the chunk entity list, not the whole trackedEntities map... ++ Entity[] entities = chunk.entities.getRawData(); ++ for (int i = 0, size = chunk.entities.size(); i < size; ++i) { ++ Entity entity = entities[i]; ++ if (entity == entityplayer) { ++ continue; ++ } ++ PlayerChunkMap.EntityTracker tracker = this.trackedEntities.get(entity.getId()); ++ if (tracker != null) { // dumb plugins... move on... ++ tracker.updatePlayer(entityplayer); ++ } + +- while (objectiterator.hasNext()) { +- PlayerChunkMap.EntityTracker playerchunkmap_entitytracker = (PlayerChunkMap.EntityTracker) objectiterator.next(); +- Entity entity = playerchunkmap_entitytracker.tracker; ++ // keep the vanilla logic here - this is REQUIRED or else passengers and their vehicles disappear! ++ // (and god knows what the leash thing is) + +- if (entity != entityplayer && entity.chunkX == chunk.getPos().x && entity.chunkZ == chunk.getPos().z) { +- playerchunkmap_entitytracker.updatePlayer(entityplayer); +- if (entity instanceof EntityInsentient && ((EntityInsentient) entity).getLeashHolder() != null) { +- list.add(entity); +- } ++ if (entity instanceof EntityInsentient && ((EntityInsentient)entity).getLeashHolder() != null) { ++ list.add(entity); ++ } + +- if (!entity.getPassengers().isEmpty()) { +- list1.add(entity); +- } ++ if (!entity.getPassengers().isEmpty()) { ++ list1.add(entity); + } + } ++ // Paper end - optimise entity tracker + + Iterator iterator; + Entity entity1; +@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { + + public class EntityTracker { + +- private final EntityTrackerEntry trackerEntry; ++ final EntityTrackerEntry trackerEntry; // Paper - private -> package private + private final Entity tracker; + private final int trackingDistance; + private SectionPosition e; +@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { + this.e = SectionPosition.a(entity); + } + ++ // Paper start - use distance map to optimise tracker ++ com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet lastTrackerCandidates; ++ ++ final void updatePlayers(com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet newTrackerCandidates) { ++ com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet oldTrackerCandidates = this.lastTrackerCandidates; ++ this.lastTrackerCandidates = newTrackerCandidates; ++ ++ if (newTrackerCandidates != null) { ++ Object[] rawData = newTrackerCandidates.getBackingSet(); ++ for (int i = 0, len = rawData.length; i < len; ++i) { ++ Object raw = rawData[i]; ++ if (!(raw instanceof EntityPlayer)) { ++ continue; ++ } ++ EntityPlayer player = (EntityPlayer)raw; ++ this.updatePlayer(player); ++ } ++ } ++ ++ if (oldTrackerCandidates == newTrackerCandidates) { ++ // this is likely the case. ++ // means there has been no range changes, so we can just use the above for tracking. ++ return; ++ } ++ ++ // stuff could have been removed, so we need to check the trackedPlayers set ++ // for players that were removed ++ ++ for (EntityPlayer player : this.trackedPlayers.toArray(new EntityPlayer[0])) { // avoid CME ++ if (newTrackerCandidates == null || !newTrackerCandidates.contains(player)) { ++ this.updatePlayer(player); ++ } ++ } ++ } ++ // Paper end - use distance map to optimise tracker ++ + public boolean equals(Object object) { + return object instanceof PlayerChunkMap.EntityTracker ? ((PlayerChunkMap.EntityTracker) object).tracker.getId() == this.tracker.getId() : false; + } +@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { + int j = entity.getEntityType().getChunkRange() * 16; + j = org.spigotmc.TrackingRange.getEntityTrackingRange(entity, j); // Paper + +- if (j > i) { ++ if (j < i) { // Paper - we need the lowest range thanks to the fact that our tracker doesn't account for passenger logic + i = j; + } + } +diff --git a/src/main/java/org/spigotmc/TrackingRange.java b/src/main/java/org/spigotmc/TrackingRange.java +index 765bdaf9b5..43b5ed8e39 100644 +--- a/src/main/java/org/spigotmc/TrackingRange.java ++++ b/src/main/java/org/spigotmc/TrackingRange.java +@@ -0,0 +0,0 @@ public class TrackingRange + return config.otherTrackingRange; + } + } ++ ++ // Paper start - optimise entity tracking ++ // copied from above, TODO check on update ++ public static TrackingRangeType getTrackingRangeType(Entity entity) ++ { ++ if ( entity instanceof EntityPlayer ) ++ { ++ return TrackingRangeType.PLAYER; ++ // Paper start - Simplify and set water mobs to animal tracking range ++ } ++ switch (entity.activationType) { ++ case RAIDER: ++ case MONSTER: ++ return TrackingRangeType.MONSTER; ++ case WATER: ++ case ANIMAL: ++ return TrackingRangeType.ANIMAL; ++ case MISC: ++ } ++ if ( entity instanceof EntityItemFrame || entity instanceof EntityPainting || entity instanceof EntityItem || entity instanceof EntityExperienceOrb ) ++ // Paper end ++ { ++ return TrackingRangeType.MISC; ++ } else ++ { ++ if (entity instanceof EntityEnderDragon) return TrackingRangeType.ENDERDRAGON; // Paper - enderdragon is exempt ++ return TrackingRangeType.OTHER; ++ } ++ } ++ ++ public static enum TrackingRangeType { ++ PLAYER, ++ ANIMAL, ++ MONSTER, ++ MISC, ++ OTHER, ++ ENDERDRAGON; ++ } ++ // Paper end - optimise entity tracking + } +-- \ No newline at end of file diff --git a/Spigot-Server-Patches/Validate-PickItem-Packet-and-kick-for-invalid.patch b/Spigot-Server-Patches/Validate-PickItem-Packet-and-kick-for-invalid.patch index 0dac8096b4..7b1a6819f2 100644 --- a/Spigot-Server-Patches/Validate-PickItem-Packet-and-kick-for-invalid.patch +++ b/Spigot-Server-Patches/Validate-PickItem-Packet-and-kick-for-invalid.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Validate PickItem Packet and kick for invalid diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java -index 376f7f8f0b..a33289749c 100644 +index a180df220e..02bda8bee4 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 { diff --git a/Spigot-Server-Patches/implement-optional-per-player-mob-spawns.patch b/Spigot-Server-Patches/implement-optional-per-player-mob-spawns.patch index 372ecf7f92..3530ff4732 100644 --- a/Spigot-Server-Patches/implement-optional-per-player-mob-spawns.patch +++ b/Spigot-Server-Patches/implement-optional-per-player-mob-spawns.patch @@ -643,7 +643,7 @@ index 8427ee2ee8..0f04bcc8b7 100644 return this.bb; } diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java -index 19603343b2..a7b981f299 100644 +index 43abdb47fd..0fd1d6b3e6 100644 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { @@ -755,7 +755,7 @@ index fdac5bb3a2..58bbf2f9d2 100644 @Nullable diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index f9aed78188..fd8ca2a510 100644 +index 731f6a8320..38c5b721bf 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 { diff --git a/Spigot-Server-Patches/incremental-chunk-saving.patch b/Spigot-Server-Patches/incremental-chunk-saving.patch index 293554a2a3..496ee32c71 100644 --- a/Spigot-Server-Patches/incremental-chunk-saving.patch +++ b/Spigot-Server-Patches/incremental-chunk-saving.patch @@ -29,7 +29,7 @@ index 071e5e7f72..4867615215 100644 + } } diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java -index 7bcdbe713d..4b77934c39 100644 +index 165cb994e8..af0d6aff4d 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 { @@ -175,7 +175,7 @@ index a640cb3845..3d255b1964 100644 public void a(ProtoChunkExtension protochunkextension) { for (int i = 0; i < this.statusFutures.length(); ++i) { diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java -index 6122d19ccf..4682dca9de 100644 +index 34f470779f..4f5b516144 100644 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { @@ -261,7 +261,7 @@ index 6122d19ccf..4682dca9de 100644 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 389c9d03a1..62c2275098 100644 +index ce506e0e12..ad5e538b24 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 {