From c18ae50aab3de1d905c7ea59d81735876bf78330 Mon Sep 17 00:00:00 2001 From: Simon Gardling Date: Fri, 19 Feb 2021 14:39:10 -0500 Subject: [PATCH] Updated Upstream and Sidestream(s) (Paper/Tuinity/Purpur/Airplane/Empirecraft) (#412) Upstream/An Sidestream has released updates that appears to apply and compile correctly This update has NOT been tested by YatopiaMC and as with ANY update, please do your own testing. Paper Changes: 0ea308381 Updated Upstream (Bukkit/CraftBukkit) Tuinity Changes: a539774 Fix off-by-one for BasicEntityList 0763cd1 Updated Upstream (Paper) ad35543 Various optimisations 2006b9b Discord vanity URL Purpur Changes: 4086888 [ci-skip] Fix formatting issue in previous commit 70ec0e2 Updated Upstream (Paper & Tuinity) d7d72b3 Remove unused event from api 6ec1ed7 [ci-skip] hmm Airplane Changes: 7dc1546 Updated Upstream (Tuinity) 04fd4dc Updated Upstream (Tuinity) Empirecraft Changes: 586aef63 Prevent grindstones from overstacking items 4cf96630 Updated Paper --- PATCHES.md | 7 +- Paper | 2 +- buildSrc/src/main/kotlin/task/ApplyPatches.kt | 2 + ...cing-for-EntityLiving-hasLineOfSight.patch | 4 +- ...0006-Queue-lighting-update-only-once.patch | 81 -- ...odifiableMap-instead-of-making-copy.patch} | 0 ...priority-of-checks-in-chunk-ticking.patch} | 4 +- ...008-Reduce-projectile-chunk-loading.patch} | 0 ...imize-random-calls-in-chunk-ticking.patch} | 24 +- ...-get-entity-equipment-if-not-needed.patch} | 0 ...ch => 0011-Dynamic-activation-range.patch} | 2 +- ...cs-improve-perf-of-StructureManager.patch} | 0 ...y.patch => 0013-Cache-palette-array.patch} | 0 ...> 0014-Reduce-chunk-loading-lookups.patch} | 2 +- ...h => 0015-Reduce-memory-allocations.patch} | 22 +- .../0003-dont-load-chunks-for-physics.patch | 4 +- ...-grindstones-from-overstacking-items.patch | 19 + .../server/0001-Origami-Server-Config.patch | 4 +- ...0015-PaperPR-PlayerItemCooldownEvent.patch | 89 -- ...ch => 0015-Player-invulnerabilities.patch} | 0 ...7-Anvil-API.patch => 0016-Anvil-API.patch} | 0 ... 0017-ItemStack-convenience-methods.patch} | 0 ...d-to-crystals-and-crystals-shoot-ph.patch} | 0 ...atch => 0019-ChatColor-conveniences.patch} | 0 ...021-Ridables.patch => 0020-Ridables.patch} | 0 ...gurable-permission-message-upgrades.patch} | 0 ...022-LivingEntity-broadcastItemBreak.patch} | 0 ...atch => 0023-Item-entity-immunities.patch} | 0 ...t-Improve-output-of-plugins-command.patch} | 0 ...able-zombie-aggressiveness-towards-.patch} | 0 ...-to-recipe-s-ExactChoice-ingredient.patch} | 0 ...check-to-EntityDamagedByEntityEvent.patch} | 0 ...d-API.patch => 0028-Left-handed-API.patch} | 0 ...29-Alphabetize-in-game-plugins-list.patch} | 0 ...lf-API.patch => 0030-Rabid-Wolf-API.patch} | 0 ...c-warnings-missing-param-and-return.patch} | 0 ...tch => 0032-PlayerBookTooLargeEvent.patch} | 0 ...herite-armor-grants-fire-resistance.patch} | 0 ...034-Add-EntityTeleportHinderedEvent.patch} | 0 ... => 0035-Add-StructureGenerateEvent.patch} | 0 ...Add-unsafe-Entity-serialization-API.patch} | 0 .../server/0002-Purpur-config-files.patch | 4 +- .../Purpur/patches/server/0008-AFK-API.patch | 8 +- .../server/0025-Giants-AI-settings.patch | 2 +- .../0027-Zombie-horse-naturally-spawn.patch | 4 +- .../server/0037-Cat-spawning-options.patch | 2 +- ...up-loot-bypass-mob-griefing-gamerule.patch | 2 +- ...0061-Villagers-follow-emerald-blocks.patch | 4 +- .../0062-Allow-leashing-villagers.patch | 6 +- ...ispenser-curse-of-binding-protection.patch | 2 +- .../0079-Add-phantom-spawning-options.patch | 6 +- ...-Add-allow-water-in-end-world-option.patch | 4 +- .../patches/server/0084-Entity-lifespan.patch | 2 +- .../server/0100-Add-no-tick-block-list.patch | 4 +- .../Purpur/patches/server/0104-Ridables.patch | 16 +- ...ggling-special-MobSpawners-per-world.patch | 10 +- .../0120-Configurable-daylight-cycle.patch | 8 +- ...justable-breeding-cooldown-to-config.patch | 4 +- ...39-Changeable-Mob-Left-Handed-Chance.patch | 2 +- ...-Configurable-entity-base-attributes.patch | 4 +- ...oggle-for-water-sensitive-mob-damage.patch | 2 +- .../patches/server/0004-Util-patch.patch | 18 +- .../server/0008-Add-soft-async-catcher.patch | 6 +- ...l-more-information-in-watchdog-dumps.patch | 2 +- .../0015-Execute-chunk-tasks-mid-tick.patch | 23 +- ...ush-calls-for-entity-tracker-packets.patch | 4 +- ...0-Make-CallbackExecutor-strict-again.patch | 2 +- ...single-and-multi-AABB-VoxelShapes-an.patch | 2 +- .../0027-Optimise-chunk-tick-iteration.patch | 6 +- ...ework-PlayerChunk-main-thread-checks.patch | 14 +- ...o-be-removed-from-a-world-while-tick.patch | 6 +- ...alls-removing-tickets-for-sync-loads.patch | 8 +- .../0038-Distance-manager-tick-timings.patch | 6 +- ...heck-flag-dirty-calls-in-PlayerChunk.patch | 6 +- ...ket-level-changes-while-unloading-pl.patch | 4 +- ...osest-entity-lookup-used-by-AI-goals.patch | 472 --------- .../0046-Optimise-closest-entity-lookup.patch | 985 ++++++++++++++++++ ...timise-EntityInsentient-checkDespawn.patch | 273 ----- .../0047-Optimise-nearby-player-lookups.patch | 476 +++++++++ .../0048-Remove-streams-for-villager-AI.patch | 7 +- ...ayerchunkmap-instance-in-light-threa.patch | 4 +- ...eue-overfill-when-no-players-are-onl.patch | 17 +- .../0061-Rewrite-the-light-engine.patch | 28 +- .../0062-Optimise-WorldServer-notify.patch | 22 +- .../0063-Actually-unload-POI-data.patch | 10 +- ...chunks-refusing-to-unload-at-low-TPS.patch | 4 +- ...0019-Optimize-TileEntity-load-unload.patch | 2 +- ...ze-some-stuff-in-WorldServer-ticking.patch | 12 +- ...-Fix-LightEngineThreaded-memory-leak.patch | 4 +- patches/server/0059-Port-hydrogen.patch | 6 +- .../0063-Suspected-plugins-report.patch | 4 +- upstream/Airplane | 2 +- upstream/Empirecraft | 2 +- upstream/Purpur | 2 +- upstream/Tuinity | 2 +- upstreamCommits/Airplane | 2 +- upstreamCommits/Empirecraft | 2 +- upstreamCommits/Purpur | 2 +- upstreamCommits/Tuinity | 2 +- upstreamConfig/0003-Airplane.properties | 4 +- upstreamConfig/0005-Empirecraft.properties | 2 +- 101 files changed, 1703 insertions(+), 1114 deletions(-) delete mode 100644 patches/Airplane/patches/server/0006-Queue-lighting-update-only-once.patch rename patches/Airplane/patches/server/{0007-Use-unmodifiableMap-instead-of-making-copy.patch => 0006-Use-unmodifiableMap-instead-of-making-copy.patch} (100%) rename patches/Airplane/patches/server/{0008-Swap-priority-of-checks-in-chunk-ticking.patch => 0007-Swap-priority-of-checks-in-chunk-ticking.patch} (92%) rename patches/Airplane/patches/server/{0009-Reduce-projectile-chunk-loading.patch => 0008-Reduce-projectile-chunk-loading.patch} (100%) rename patches/Airplane/patches/server/{0010-Optimize-random-calls-in-chunk-ticking.patch => 0009-Optimize-random-calls-in-chunk-ticking.patch} (86%) rename patches/Airplane/patches/server/{0011-Don-t-get-entity-equipment-if-not-needed.patch => 0010-Don-t-get-entity-equipment-if-not-needed.patch} (100%) rename patches/Airplane/patches/server/{0012-Dynamic-activation-range.patch => 0011-Dynamic-activation-range.patch} (99%) rename patches/Airplane/patches/server/{0013-Reduce-allocs-improve-perf-of-StructureManager.patch => 0012-Reduce-allocs-improve-perf-of-StructureManager.patch} (100%) rename patches/Airplane/patches/server/{0014-Cache-palette-array.patch => 0013-Cache-palette-array.patch} (100%) rename patches/Airplane/patches/server/{0015-Reduce-chunk-loading-lookups.patch => 0014-Reduce-chunk-loading-lookups.patch} (97%) rename patches/Airplane/patches/server/{0016-Reduce-memory-allocations.patch => 0015-Reduce-memory-allocations.patch} (93%) create mode 100644 patches/Empirecraft/patches/server/0004-Prevent-grindstones-from-overstacking-items.patch delete mode 100644 patches/Purpur/patches/api/0015-PaperPR-PlayerItemCooldownEvent.patch rename patches/Purpur/patches/api/{0016-Player-invulnerabilities.patch => 0015-Player-invulnerabilities.patch} (100%) rename patches/Purpur/patches/api/{0017-Anvil-API.patch => 0016-Anvil-API.patch} (100%) rename patches/Purpur/patches/api/{0018-ItemStack-convenience-methods.patch => 0017-ItemStack-convenience-methods.patch} (100%) rename patches/Purpur/patches/api/{0019-Phantoms-attracted-to-crystals-and-crystals-shoot-ph.patch => 0018-Phantoms-attracted-to-crystals-and-crystals-shoot-ph.patch} (100%) rename patches/Purpur/patches/api/{0020-ChatColor-conveniences.patch => 0019-ChatColor-conveniences.patch} (100%) rename patches/Purpur/patches/api/{0021-Ridables.patch => 0020-Ridables.patch} (100%) rename patches/Purpur/patches/api/{0022-Configurable-permission-message-upgrades.patch => 0021-Configurable-permission-message-upgrades.patch} (100%) rename patches/Purpur/patches/api/{0023-LivingEntity-broadcastItemBreak.patch => 0022-LivingEntity-broadcastItemBreak.patch} (100%) rename patches/Purpur/patches/api/{0024-Item-entity-immunities.patch => 0023-Item-entity-immunities.patch} (100%) rename patches/Purpur/patches/api/{0025-Spigot-Improve-output-of-plugins-command.patch => 0024-Spigot-Improve-output-of-plugins-command.patch} (100%) rename patches/Purpur/patches/api/{0026-Add-option-to-disable-zombie-aggressiveness-towards-.patch => 0025-Add-option-to-disable-zombie-aggressiveness-towards-.patch} (100%) rename patches/Purpur/patches/api/{0027-Add-predicate-to-recipe-s-ExactChoice-ingredient.patch => 0026-Add-predicate-to-recipe-s-ExactChoice-ingredient.patch} (100%) rename patches/Purpur/patches/api/{0028-Add-critical-hit-check-to-EntityDamagedByEntityEvent.patch => 0027-Add-critical-hit-check-to-EntityDamagedByEntityEvent.patch} (100%) rename patches/Purpur/patches/api/{0029-Left-handed-API.patch => 0028-Left-handed-API.patch} (100%) rename patches/Purpur/patches/api/{0030-Alphabetize-in-game-plugins-list.patch => 0029-Alphabetize-in-game-plugins-list.patch} (100%) rename patches/Purpur/patches/api/{0031-Rabid-Wolf-API.patch => 0030-Rabid-Wolf-API.patch} (100%) rename patches/Purpur/patches/api/{0032-Fix-javadoc-warnings-missing-param-and-return.patch => 0031-Fix-javadoc-warnings-missing-param-and-return.patch} (100%) rename patches/Purpur/patches/api/{0033-PlayerBookTooLargeEvent.patch => 0032-PlayerBookTooLargeEvent.patch} (100%) rename patches/Purpur/patches/api/{0034-Full-netherite-armor-grants-fire-resistance.patch => 0033-Full-netherite-armor-grants-fire-resistance.patch} (100%) rename patches/Purpur/patches/api/{0035-Add-EntityTeleportHinderedEvent.patch => 0034-Add-EntityTeleportHinderedEvent.patch} (100%) rename patches/Purpur/patches/api/{0036-Add-StructureGenerateEvent.patch => 0035-Add-StructureGenerateEvent.patch} (100%) rename patches/Purpur/patches/api/{0037-Add-unsafe-Entity-serialization-API.patch => 0036-Add-unsafe-Entity-serialization-API.patch} (100%) delete mode 100644 patches/Tuinity/patches/server/0046-Optimise-closest-entity-lookup-used-by-AI-goals.patch create mode 100644 patches/Tuinity/patches/server/0046-Optimise-closest-entity-lookup.patch delete mode 100644 patches/Tuinity/patches/server/0047-Optimise-EntityInsentient-checkDespawn.patch create mode 100644 patches/Tuinity/patches/server/0047-Optimise-nearby-player-lookups.patch diff --git a/PATCHES.md b/PATCHES.md index b71a7e4b..524a6163 100644 --- a/PATCHES.md +++ b/PATCHES.md @@ -248,12 +248,12 @@ # Patches | server | New nbt cache | Hugo Planque | ishland | | server | Nuke streams off BlockPosition | Ivan Pekov | | | server | Nuke streams off SectionPosition | Ivan Pekov | | -| server | Optimise EntityInsentient#checkDespawn | Spottedleaf | | | server | Optimise WorldServer#notify | Spottedleaf | | | server | Optimise chunk tick iteration | Spottedleaf | | -| server | Optimise closest entity lookup used by AI goals | Spottedleaf | | +| server | Optimise closest entity lookup | Spottedleaf | | | server | Optimise collision checking in player move packet handling | Spottedleaf | | | server | Optimise entity hard collision checking | Spottedleaf | | +| server | Optimise nearby player lookups | Spottedleaf | | | server | Optimise non-flush packet sending | Spottedleaf | | | server | Optimise portals | Ivan Pekov | | | server | Optimise tab complete | Spottedleaf | | @@ -275,7 +275,6 @@ # Patches | server | PaperPR - Add hex color code support for console logging | Esophose | | | server | PaperPR - Config option for Piglins guarding chests | jmp | | | server | PaperPR - Fix username connecting with no texture being | Camotoy | | -| api | PaperPR - PlayerItemCooldownEvent | KennyTV | | | server | Per World Spawn Limits | Chase Whipple | | | server | Per entity (type) collision settings | MrIvanPlays | tr7zw | | server | Persistent TileEntity Lore and DisplayName | jmp | | @@ -296,13 +295,13 @@ # Patches | server | Populator seed controls | Spottedleaf | | | server | Port hydrogen | JellySquid | | | server | Preload ProtocolLib EnumWrappers | ishland | | +| server | Prevent grindstones from overstacking items | chickeneer | | | server | Prevent light queue overfill when no players are online | Spottedleaf | | | server | Prevent long map entry creation in light engine | Spottedleaf | | | server | Prevent unload() calls removing tickets for sync loads | Spottedleaf | | | server | Properly handle cancellation of projectile hit event | Spottedleaf | | | server | Purpur config files | William Blake Galbreath | | | api | Purpur config files | William Blake Galbreath | | -| server | Queue lighting update only once | Paul Sauve | | | server | Rabbit naturally spawn toast and killer | William Blake Galbreath | | | api | Rabid Wolf API | Encode42 | | | server | Raid cooldown setting | jmp | | diff --git a/Paper b/Paper index 088fa6f2..0ea30838 160000 --- a/Paper +++ b/Paper @@ -1 +1 @@ -Subproject commit 088fa6f28b029e58cfe286608fff9803f932a512 +Subproject commit 0ea3083817707d792ebac246895455a0aa0d3425 diff --git a/buildSrc/src/main/kotlin/task/ApplyPatches.kt b/buildSrc/src/main/kotlin/task/ApplyPatches.kt index e73458d2..ef425e42 100644 --- a/buildSrc/src/main/kotlin/task/ApplyPatches.kt +++ b/buildSrc/src/main/kotlin/task/ApplyPatches.kt @@ -26,6 +26,8 @@ internal fun Project.createApplyPatchesTask( } fun applyPatches(patchDir: Path, applyName: String, name: String, wasGitSigningEnabled: Boolean, projectDir: File): Boolean { + if (Files.notExists(patchDir)) return true + val patchPaths = Files.newDirectoryStream(patchDir) .map { it.toFile() } .filter { it.name.endsWith(".patch") } diff --git a/patches/Airplane/patches/server/0004-Strip-raytracing-for-EntityLiving-hasLineOfSight.patch b/patches/Airplane/patches/server/0004-Strip-raytracing-for-EntityLiving-hasLineOfSight.patch index e30a972f..a6389ec0 100644 --- a/patches/Airplane/patches/server/0004-Strip-raytracing-for-EntityLiving-hasLineOfSight.patch +++ b/patches/Airplane/patches/server/0004-Strip-raytracing-for-EntityLiving-hasLineOfSight.patch @@ -88,10 +88,10 @@ index 2e7721a650c5a351b3584665bd236f92ef577761..b3c2b461b2a654a9e37a57f2f62b3ba8 return d0 == 0.0D ? 0 : (d0 > 0.0D ? 1 : -1); } diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index 7c367fe6152c30aab3e53c8f88cceba606891c93..6e6059daba05d7ce3aabeed85cc0e0d2daa04f92 100644 +index 87766db4e3c2e522b738fa304a861dc0985d878a..44f52fb6e3aedeadec4be3979ad1c625643cf9fa 100644 --- a/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java -@@ -332,6 +332,91 @@ public abstract class World implements GeneratorAccess, AutoCloseable { +@@ -363,6 +363,91 @@ public abstract class World implements GeneratorAccess, AutoCloseable { return null; } diff --git a/patches/Airplane/patches/server/0006-Queue-lighting-update-only-once.patch b/patches/Airplane/patches/server/0006-Queue-lighting-update-only-once.patch deleted file mode 100644 index 95c5bc84..00000000 --- a/patches/Airplane/patches/server/0006-Queue-lighting-update-only-once.patch +++ /dev/null @@ -1,81 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Paul Sauve -Date: Sat, 31 Oct 2020 19:03:25 -0500 -Subject: [PATCH] Queue lighting update only once - -Airplane -Copyright (C) 2020 Technove LLC - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . - -diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java -index 9e6381a60b804a957eda5b72582d5545faebcb3e..1da5c7def8b476cf638548b05d3e2015bc372f51 100644 ---- a/src/main/java/net/minecraft/server/ChunkProviderServer.java -+++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java -@@ -996,6 +996,7 @@ public class ChunkProviderServer extends IChunkProvider { - // Paper - moved up - // Tuinity start - optimise chunk tick iteration - com.tuinity.tuinity.util.maplist.IteratorSafeOrderedReferenceSet.Iterator iterator = this.entityTickingChunks.iterator(); -+ boolean updateLighting = false; // Airplane - try { - while (iterator.hasNext()) { - Chunk chunk = iterator.next(); -@@ -1020,7 +1021,7 @@ public class ChunkProviderServer extends IChunkProvider { - } - - this.world.timings.chunkTicks.startTiming(); // Spigot // Paper -- this.world.a(chunk, k); -+ if (this.world.abool(chunk, k)) updateLighting = true; // Airplane - this.world.timings.chunkTicks.stopTiming(); // Spigot // Paper - MinecraftServer.getServer().executeMidTickTasks(); // Tuinity - exec chunk tasks during world tick - } -@@ -1030,6 +1031,7 @@ public class ChunkProviderServer extends IChunkProvider { - } finally { - iterator.finishedIterating(); - } -+ if (updateLighting) this.getLightEngine().queueUpdate(); // Airplane - // Tuinity end - optimise chunk tick iteration - this.world.getMethodProfiler().enter("customSpawners"); - if (flag1) { -diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index 307794aebb4ccd4d409013ed485e6defda2149ca..f599f80a543cfd3de97e5f80372ffed6c7bfd9ff 100644 ---- a/src/main/java/net/minecraft/server/WorldServer.java -+++ b/src/main/java/net/minecraft/server/WorldServer.java -@@ -1027,7 +1027,10 @@ public class WorldServer extends World implements GeneratorAccessSeed { - private final com.destroystokyo.paper.util.math.ThreadUnsafeRandom randomTickRandom = new com.destroystokyo.paper.util.math.ThreadUnsafeRandom(); - // Paper end - -- public void a(Chunk chunk, int i) { final int randomTickSpeed = i; // Paper -+ // Airplane start - create version of chunk tick that returns a bool for updating lighting -+ public void a(Chunk chunk, int i) { this.abool(chunk, i); } -+ public boolean abool(Chunk chunk, int i) { final int randomTickSpeed = i; // Paper -+ // Airplane end - ChunkCoordIntPair chunkcoordintpair = chunk.getPos(); - boolean flag = this.isRaining(); - int j = chunkcoordintpair.d(); -@@ -1136,9 +1139,13 @@ public class WorldServer extends World implements GeneratorAccessSeed { - } - gameprofilerfiller.exit(); - timings.chunkTicksBlocks.stopTiming(); // Paper -- getChunkProvider().getLightEngine().queueUpdate(); // Paper -+ // Airplane start -+ //getChunkProvider().getLightEngine().queueUpdate(); // Paper -+ return true; -+ // Airplane end - // Paper end - } -+ return false; // Airplane - } - - protected BlockPosition a(BlockPosition blockposition) { diff --git a/patches/Airplane/patches/server/0007-Use-unmodifiableMap-instead-of-making-copy.patch b/patches/Airplane/patches/server/0006-Use-unmodifiableMap-instead-of-making-copy.patch similarity index 100% rename from patches/Airplane/patches/server/0007-Use-unmodifiableMap-instead-of-making-copy.patch rename to patches/Airplane/patches/server/0006-Use-unmodifiableMap-instead-of-making-copy.patch diff --git a/patches/Airplane/patches/server/0008-Swap-priority-of-checks-in-chunk-ticking.patch b/patches/Airplane/patches/server/0007-Swap-priority-of-checks-in-chunk-ticking.patch similarity index 92% rename from patches/Airplane/patches/server/0008-Swap-priority-of-checks-in-chunk-ticking.patch rename to patches/Airplane/patches/server/0007-Swap-priority-of-checks-in-chunk-ticking.patch index 169fee6f..faf080ac 100644 --- a/patches/Airplane/patches/server/0008-Swap-priority-of-checks-in-chunk-ticking.patch +++ b/patches/Airplane/patches/server/0007-Swap-priority-of-checks-in-chunk-ticking.patch @@ -23,10 +23,10 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index f599f80a543cfd3de97e5f80372ffed6c7bfd9ff..fdab9a50bc5d433c76fda1501110524792a749c8 100644 +index 5d92398369862881d997c270671ddb6b78ed2cb4..6694a669f9fbae0dce857e97651ed527f5481427 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java -@@ -1040,7 +1040,7 @@ public class WorldServer extends World implements GeneratorAccessSeed { +@@ -1134,7 +1134,7 @@ public class WorldServer extends World implements GeneratorAccessSeed { gameprofilerfiller.enter("thunder"); final BlockPosition.MutableBlockPosition blockposition = this.chunkTickMutablePosition; // Paper - use mutable to reduce allocation rate, final to force compile fail on change diff --git a/patches/Airplane/patches/server/0009-Reduce-projectile-chunk-loading.patch b/patches/Airplane/patches/server/0008-Reduce-projectile-chunk-loading.patch similarity index 100% rename from patches/Airplane/patches/server/0009-Reduce-projectile-chunk-loading.patch rename to patches/Airplane/patches/server/0008-Reduce-projectile-chunk-loading.patch diff --git a/patches/Airplane/patches/server/0010-Optimize-random-calls-in-chunk-ticking.patch b/patches/Airplane/patches/server/0009-Optimize-random-calls-in-chunk-ticking.patch similarity index 86% rename from patches/Airplane/patches/server/0010-Optimize-random-calls-in-chunk-ticking.patch rename to patches/Airplane/patches/server/0009-Optimize-random-calls-in-chunk-ticking.patch index e25c4225..810cbe9c 100644 --- a/patches/Airplane/patches/server/0010-Optimize-random-calls-in-chunk-ticking.patch +++ b/patches/Airplane/patches/server/0009-Optimize-random-calls-in-chunk-ticking.patch @@ -34,7 +34,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java -index 68d6fb69a0c1b98b3c11b6d80783faaa58272526..fa1d559a07199bf52d8ae04b2c34261efdebdcdb 100644 +index 8fda4702764e80dae93ef9c0eb53abc198642ab1..0924f6b484468f3cf3c2d405101c0158c12d69e6 100644 --- a/src/main/java/net/minecraft/server/Chunk.java +++ b/src/main/java/net/minecraft/server/Chunk.java @@ -53,6 +53,18 @@ public class Chunk implements IChunkAccess { @@ -56,19 +56,19 @@ index 68d6fb69a0c1b98b3c11b6d80783faaa58272526..fa1d559a07199bf52d8ae04b2c34261e public Chunk(World world, ChunkCoordIntPair chunkcoordintpair, BiomeStorage biomestorage) { this(world, chunkcoordintpair, biomestorage, ChunkConverter.a, TickListEmpty.b(), TickListEmpty.b(), 0L, (ChunkSection[]) null, (Consumer) null); } -@@ -325,6 +337,7 @@ public class Chunk implements IChunkAccess { - +@@ -287,6 +299,7 @@ public class Chunk implements IChunkAccess { // CraftBukkit start this.bukkitChunk = new org.bukkit.craftbukkit.CraftChunk(this); + this.entitySlicesManager = new com.tuinity.tuinity.world.ChunkEntitySlices(this.world, this.loc.x, this.loc.z, 0, 15); // TODO update for 1.17 // Tuinity + this.lightningTick = this.world.random.nextInt(100000) << 1; // Airplane - initialize lightning tick } public org.bukkit.Chunk bukkitChunk; diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java -index 1da5c7def8b476cf638548b05d3e2015bc372f51..03bcd704e3c08f5b54b124df1583e3ccdb4cb485 100644 +index 18270d44185b0ec41b9b6e1d2135e7aae3b33261..e8a6bc2654e840395fee70d79695c5a395a4fc1b 100644 --- a/src/main/java/net/minecraft/server/ChunkProviderServer.java +++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java -@@ -965,6 +965,7 @@ public class ChunkProviderServer extends IChunkProvider { +@@ -973,6 +973,7 @@ public class ChunkProviderServer extends IChunkProvider { } // Paper end - optimize isOutisdeRange this.world.getMethodProfiler().enter("pollingChunks"); @@ -77,19 +77,19 @@ index 1da5c7def8b476cf638548b05d3e2015bc372f51..03bcd704e3c08f5b54b124df1583e3cc boolean flag2 = world.ticksPerAnimalSpawns != 0L && worlddata.getTime() % world.ticksPerAnimalSpawns == 0L; // CraftBukkit diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index fdab9a50bc5d433c76fda1501110524792a749c8..6dc1f6d7f734b8c769c86109701155ebe9c2f6bd 100644 +index 6694a669f9fbae0dce857e97651ed527f5481427..dd9ae27a208b5e55a1c473eda6e068a0fc3eb64f 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java -@@ -1027,6 +1027,8 @@ public class WorldServer extends World implements GeneratorAccessSeed { +@@ -1124,6 +1124,8 @@ public class WorldServer extends World implements GeneratorAccessSeed { private final com.destroystokyo.paper.util.math.ThreadUnsafeRandom randomTickRandom = new com.destroystokyo.paper.util.math.ThreadUnsafeRandom(); // Paper end + private int currentIceAndSnowTick = 0; protected void resetIceAndSnowTick() { this.currentIceAndSnowTick = this.randomTickRandom.nextInt(16); } // Airplane + - // Airplane start - create version of chunk tick that returns a bool for updating lighting - public void a(Chunk chunk, int i) { this.abool(chunk, i); } - public boolean abool(Chunk chunk, int i) { final int randomTickSpeed = i; // Paper -@@ -1040,7 +1042,7 @@ public class WorldServer extends World implements GeneratorAccessSeed { + public void a(Chunk chunk, int i) { final int randomTickSpeed = i; // Paper + ChunkCoordIntPair chunkcoordintpair = chunk.getPos(); + boolean flag = this.isRaining(); +@@ -1134,7 +1136,7 @@ public class WorldServer extends World implements GeneratorAccessSeed { gameprofilerfiller.enter("thunder"); final BlockPosition.MutableBlockPosition blockposition = this.chunkTickMutablePosition; // Paper - use mutable to reduce allocation rate, final to force compile fail on change @@ -98,7 +98,7 @@ index fdab9a50bc5d433c76fda1501110524792a749c8..6dc1f6d7f734b8c769c86109701155eb blockposition.setValues(this.a(this.a(j, 0, k, 15))); // Paper if (this.isRainingAt(blockposition)) { DifficultyDamageScaler difficultydamagescaler = this.getDamageScaler(blockposition); -@@ -1070,7 +1072,7 @@ public class WorldServer extends World implements GeneratorAccessSeed { +@@ -1164,7 +1166,7 @@ public class WorldServer extends World implements GeneratorAccessSeed { } gameprofilerfiller.exitEnter("iceandsnow"); diff --git a/patches/Airplane/patches/server/0011-Don-t-get-entity-equipment-if-not-needed.patch b/patches/Airplane/patches/server/0010-Don-t-get-entity-equipment-if-not-needed.patch similarity index 100% rename from patches/Airplane/patches/server/0011-Don-t-get-entity-equipment-if-not-needed.patch rename to patches/Airplane/patches/server/0010-Don-t-get-entity-equipment-if-not-needed.patch diff --git a/patches/Airplane/patches/server/0012-Dynamic-activation-range.patch b/patches/Airplane/patches/server/0011-Dynamic-activation-range.patch similarity index 99% rename from patches/Airplane/patches/server/0012-Dynamic-activation-range.patch rename to patches/Airplane/patches/server/0011-Dynamic-activation-range.patch index 29590f1c..38815ed6 100644 --- a/patches/Airplane/patches/server/0012-Dynamic-activation-range.patch +++ b/patches/Airplane/patches/server/0011-Dynamic-activation-range.patch @@ -98,7 +98,7 @@ index 4a3469aca9f9e47d2ea3f3bae6ce77f5f11d6b50..5af5b50889961b10e812598dbea657c4 ++this.conversionTicks; if (this.conversionTicks > 300) { diff --git a/src/main/java/net/minecraft/server/EntityInsentient.java b/src/main/java/net/minecraft/server/EntityInsentient.java -index 65841a7bb58e210f07c0afd74c2fd5b3873bdd60..4c2e0b8aafecbc2a4b68e2c30b64db1c692d3667 100644 +index d6a086f59d9df8ef7f727e6a83fa51a14995123e..cb094f00b6c7869632b9dacfc2c8c8e8299fddde 100644 --- a/src/main/java/net/minecraft/server/EntityInsentient.java +++ b/src/main/java/net/minecraft/server/EntityInsentient.java @@ -133,10 +133,10 @@ public abstract class EntityInsentient extends EntityLiving { diff --git a/patches/Airplane/patches/server/0013-Reduce-allocs-improve-perf-of-StructureManager.patch b/patches/Airplane/patches/server/0012-Reduce-allocs-improve-perf-of-StructureManager.patch similarity index 100% rename from patches/Airplane/patches/server/0013-Reduce-allocs-improve-perf-of-StructureManager.patch rename to patches/Airplane/patches/server/0012-Reduce-allocs-improve-perf-of-StructureManager.patch diff --git a/patches/Airplane/patches/server/0014-Cache-palette-array.patch b/patches/Airplane/patches/server/0013-Cache-palette-array.patch similarity index 100% rename from patches/Airplane/patches/server/0014-Cache-palette-array.patch rename to patches/Airplane/patches/server/0013-Cache-palette-array.patch diff --git a/patches/Airplane/patches/server/0015-Reduce-chunk-loading-lookups.patch b/patches/Airplane/patches/server/0014-Reduce-chunk-loading-lookups.patch similarity index 97% rename from patches/Airplane/patches/server/0015-Reduce-chunk-loading-lookups.patch rename to patches/Airplane/patches/server/0014-Reduce-chunk-loading-lookups.patch index 4c7474ae..89be2404 100644 --- a/patches/Airplane/patches/server/0015-Reduce-chunk-loading-lookups.patch +++ b/patches/Airplane/patches/server/0014-Reduce-chunk-loading-lookups.patch @@ -30,7 +30,7 @@ index b884addf2ce6f1ef7394658078deb2e75370654f..e20b91b36587d1191f8f9e8dd501607b boolean flag1 = iblockdata.getFluid().a((Tag) TagsFluid.WATER); diff --git a/src/main/java/net/minecraft/server/SpawnerCreature.java b/src/main/java/net/minecraft/server/SpawnerCreature.java -index ee91c33a7a2edca02caf5c71fd6429f97eac7e2d..324b78a51557cdd97e125f22eff8a4f54153d9f4 100644 +index ae17950438132c5084210252bd345517131d5a99..1016305a571a2fc211cd0e58b7210d8cfb4461d5 100644 --- a/src/main/java/net/minecraft/server/SpawnerCreature.java +++ b/src/main/java/net/minecraft/server/SpawnerCreature.java @@ -372,7 +372,10 @@ public final class SpawnerCreature { diff --git a/patches/Airplane/patches/server/0016-Reduce-memory-allocations.patch b/patches/Airplane/patches/server/0015-Reduce-memory-allocations.patch similarity index 93% rename from patches/Airplane/patches/server/0016-Reduce-memory-allocations.patch rename to patches/Airplane/patches/server/0015-Reduce-memory-allocations.patch index f755071d..16c24345 100644 --- a/patches/Airplane/patches/server/0016-Reduce-memory-allocations.patch +++ b/patches/Airplane/patches/server/0015-Reduce-memory-allocations.patch @@ -56,10 +56,10 @@ index 631eb682e81e30d2a937fd1eafccd8a9ab82d21e..dc07376845f84ea949a2153cb75d2cd9 return (EntityTypes) IRegistry.a((IRegistry) IRegistry.ENTITY_TYPE, s, (Object) entitytypes_builder.a(s)); } diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java -index 2c2becef8b56d7e5e998976222df85d2c8516c43..cde7d0e641b2e1e8e6a4ce9510a996343d62a88d 100644 +index 61570ab947b5a153a4c2bcb5a09344f060e6052d..121deda90227cb0416d6642607b24093df2baa80 100644 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java -@@ -638,7 +638,9 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { +@@ -641,7 +641,9 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { return d2 * d2 + d3 * d3; } @@ -70,7 +70,7 @@ index 2c2becef8b56d7e5e998976222df85d2c8516c43..cde7d0e641b2e1e8e6a4ce9510a99634 int i; int j; -@@ -652,12 +654,16 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { +@@ -655,12 +657,16 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { j = MathHelper.floor(entityplayer.locZ() / 16.0D); } @@ -91,7 +91,7 @@ index 2c2becef8b56d7e5e998976222df85d2c8516c43..cde7d0e641b2e1e8e6a4ce9510a99634 return Math.max(Math.abs(k), Math.abs(l)); } -@@ -2496,11 +2502,17 @@ Sections go from 0..16. Now whenever a section is not empty, it can potentially +@@ -2499,11 +2505,17 @@ Sections go from 0..16. Now whenever a section is not empty, it can potentially boolean flag1 = this.tracker.attachedToPlayer; if (!flag1) { @@ -111,7 +111,7 @@ index 2c2becef8b56d7e5e998976222df85d2c8516c43..cde7d0e641b2e1e8e6a4ce9510a99634 } } -@@ -2530,8 +2542,10 @@ Sections go from 0..16. Now whenever a section is not empty, it can potentially +@@ -2533,8 +2545,10 @@ Sections go from 0..16. Now whenever a section is not empty, it can potentially } private int b() { @@ -123,7 +123,7 @@ index 2c2becef8b56d7e5e998976222df85d2c8516c43..cde7d0e641b2e1e8e6a4ce9510a99634 Iterator iterator = collection.iterator(); while (iterator.hasNext()) { -@@ -2543,6 +2557,8 @@ Sections go from 0..16. Now whenever a section is not empty, it can potentially +@@ -2546,6 +2560,8 @@ Sections go from 0..16. Now whenever a section is not empty, it can potentially i = j; } } @@ -133,10 +133,10 @@ index 2c2becef8b56d7e5e998976222df85d2c8516c43..cde7d0e641b2e1e8e6a4ce9510a99634 return this.a(i); } diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index 6e6059daba05d7ce3aabeed85cc0e0d2daa04f92..6e4c7a9b32c9e8057db3cbcead0b75d858fd6e18 100644 +index 44f52fb6e3aedeadec4be3979ad1c625643cf9fa..8c162c5fdeaffccc9a28b592e030971fe51cafb3 100644 --- a/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java -@@ -1055,19 +1055,19 @@ public abstract class World implements GeneratorAccess, AutoCloseable { +@@ -1086,19 +1086,19 @@ public abstract class World implements GeneratorAccess, AutoCloseable { public void a(Consumer consumer, Entity entity) { try { @@ -160,10 +160,10 @@ index 6e6059daba05d7ce3aabeed85cc0e0d2daa04f92..6e4c7a9b32c9e8057db3cbcead0b75d8 // Paper start - Prevent armor stands from doing entity lookups @Override diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index 6dc1f6d7f734b8c769c86109701155ebe9c2f6bd..2289c92c8933bfa0f382167fa5790a4ea17b7c75 100644 +index dd9ae27a208b5e55a1c473eda6e068a0fc3eb64f..d4672e7fa899a39bae2d9179472b22db28a58f19 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java -@@ -915,7 +915,28 @@ public class WorldServer extends World implements GeneratorAccessSeed { +@@ -1012,7 +1012,28 @@ public class WorldServer extends World implements GeneratorAccessSeed { gameprofilerfiller.enter("tick"); if (!entity.dead && !(entity instanceof EntityComplexPart)) { @@ -192,7 +192,7 @@ index 6dc1f6d7f734b8c769c86109701155ebe9c2f6bd..2289c92c8933bfa0f382167fa5790a4e } gameprofilerfiller.exit(); -@@ -1286,9 +1307,14 @@ public class WorldServer extends World implements GeneratorAccessSeed { +@@ -1376,9 +1397,14 @@ public class WorldServer extends World implements GeneratorAccessSeed { ++entity.ticksLived; GameProfilerFiller gameprofilerfiller = this.getMethodProfiler(); diff --git a/patches/Empirecraft/patches/server/0003-dont-load-chunks-for-physics.patch b/patches/Empirecraft/patches/server/0003-dont-load-chunks-for-physics.patch index 95ae09ac..db6305b5 100644 --- a/patches/Empirecraft/patches/server/0003-dont-load-chunks-for-physics.patch +++ b/patches/Empirecraft/patches/server/0003-dont-load-chunks-for-physics.patch @@ -19,10 +19,10 @@ index 657885cdaa086293f6b5aa6f3058acd16df0ba35..8724ad342bec7c733b3c825bd62dbfa5 Block.a(iblockdata, iblockdata1, generatoraccess, blockposition_mutableblockposition, i, j); diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index 6e4c7a9b32c9e8057db3cbcead0b75d858fd6e18..c0872f8a53b862558c7fa2fe17ebb0a796da03ce 100644 +index 8c162c5fdeaffccc9a28b592e030971fe51cafb3..bfc7a1c234b5fe4aa58b48c3673f473d26561077 100644 --- a/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java -@@ -774,7 +774,8 @@ public abstract class World implements GeneratorAccess, AutoCloseable { +@@ -805,7 +805,8 @@ public abstract class World implements GeneratorAccess, AutoCloseable { public void neighborChanged(BlockPosition pos, Block blockIn, BlockPosition fromPos) { a(pos, blockIn, fromPos); } // Paper - OBFHELPER public void a(BlockPosition blockposition, Block block, BlockPosition blockposition1) { if (!this.isClientSide) { diff --git a/patches/Empirecraft/patches/server/0004-Prevent-grindstones-from-overstacking-items.patch b/patches/Empirecraft/patches/server/0004-Prevent-grindstones-from-overstacking-items.patch new file mode 100644 index 00000000..a58d43de --- /dev/null +++ b/patches/Empirecraft/patches/server/0004-Prevent-grindstones-from-overstacking-items.patch @@ -0,0 +1,19 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: chickeneer +Date: Tue, 16 Feb 2021 16:28:00 -0600 +Subject: [PATCH] Prevent grindstones from overstacking items + + +diff --git a/src/main/java/net/minecraft/server/ContainerGrindstone.java b/src/main/java/net/minecraft/server/ContainerGrindstone.java +index 39f809a37b58e008e7ef32c0759eeecbde26bc94..458d9828a9e3023dd469f76320a1d513c85fd892 100644 +--- a/src/main/java/net/minecraft/server/ContainerGrindstone.java ++++ b/src/main/java/net/minecraft/server/ContainerGrindstone.java +@@ -183,7 +183,7 @@ public class ContainerGrindstone extends Container { + i = Math.max(item.getMaxDurability() - l, 0); + itemstack2 = this.b(itemstack, itemstack1); + if (!itemstack2.e()) { +- if (!ItemStack.matches(itemstack, itemstack1)) { ++ if (!ItemStack.matches(itemstack, itemstack1) || itemstack2.getMaxStackSize() == 1) { // Paper + this.resultInventory.setItem(0, ItemStack.b); + this.c(); + return; diff --git a/patches/Origami/patches/server/0001-Origami-Server-Config.patch b/patches/Origami/patches/server/0001-Origami-Server-Config.patch index eaf96ccd..9aba9ba1 100644 --- a/patches/Origami/patches/server/0001-Origami-Server-Config.patch +++ b/patches/Origami/patches/server/0001-Origami-Server-Config.patch @@ -129,7 +129,7 @@ index 0000000000000000000000000000000000000000..fe7330fabe386966c2d203a190a00a78 +} \ No newline at end of file diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index c0872f8a53b862558c7fa2fe17ebb0a796da03ce..77c748ad07ee257742c4d36825bdd9e916b5d851 100644 +index bfc7a1c234b5fe4aa58b48c3673f473d26561077..4ffaf36b40b32be25bd1944d8b8ddbc342256947 100644 --- a/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java @@ -97,6 +97,8 @@ public abstract class World implements GeneratorAccess, AutoCloseable { @@ -141,7 +141,7 @@ index c0872f8a53b862558c7fa2fe17ebb0a796da03ce..77c748ad07ee257742c4d36825bdd9e9 public final co.aikar.timings.WorldTimingsHandler timings; // Paper public static BlockPosition lastPhysicsProblem; // Spigot private org.spigotmc.TickLimiter entityLimiter; -@@ -199,6 +201,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable { +@@ -230,6 +232,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable { this.paperConfig = new com.destroystokyo.paper.PaperWorldConfig(((WorldDataServer) worlddatamutable).getName(), this.spigotConfig); // Paper this.tuinityConfig = new com.tuinity.tuinity.config.TuinityConfig.WorldConfig(((WorldDataServer)worlddatamutable).getName()); // Tuinity - Server Config this.purpurConfig = new net.pl3x.purpur.PurpurWorldConfig(((WorldDataServer) worlddatamutable).getName(), env); // Purpur diff --git a/patches/Purpur/patches/api/0015-PaperPR-PlayerItemCooldownEvent.patch b/patches/Purpur/patches/api/0015-PaperPR-PlayerItemCooldownEvent.patch deleted file mode 100644 index 1844d2c1..00000000 --- a/patches/Purpur/patches/api/0015-PaperPR-PlayerItemCooldownEvent.patch +++ /dev/null @@ -1,89 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: KennyTV -Date: Mon, 20 Apr 2020 13:57:13 +0200 -Subject: [PATCH] PaperPR - PlayerItemCooldownEvent - - -diff --git a/src/main/java/net/pl3x/purpur/event/player/PlayerItemCooldownEvent.java b/src/main/java/net/pl3x/purpur/event/player/PlayerItemCooldownEvent.java -new file mode 100644 -index 0000000000000000000000000000000000000000..2002909f30d2bd833dc13cf09b0bc4bdae0d6757 ---- /dev/null -+++ b/src/main/java/net/pl3x/purpur/event/player/PlayerItemCooldownEvent.java -@@ -0,0 +1,77 @@ -+package net.pl3x.purpur.event.player; -+ -+import com.google.common.base.Preconditions; -+import org.bukkit.Material; -+import org.bukkit.entity.Player; -+import org.bukkit.event.Cancellable; -+import org.bukkit.event.HandlerList; -+import org.bukkit.event.player.PlayerEvent; -+import org.jetbrains.annotations.NotNull; -+ -+/** -+ * Called when a player receives a cooldown on an item. -+ */ -+public final class PlayerItemCooldownEvent extends PlayerEvent implements Cancellable { -+ private static final HandlerList handlers = new HandlerList(); -+ @NotNull -+ private final Material type; -+ private int cooldown; -+ private boolean cancelled; -+ -+ public PlayerItemCooldownEvent(@NotNull Player player, @NotNull Material type, int cooldown) { -+ super(player); -+ this.type = type; -+ this.cooldown = cooldown; -+ } -+ -+ /** -+ * Get the material affected by the cooldown. -+ * -+ * @return material affected by the cooldown -+ */ -+ @NotNull -+ public Material getType() { -+ return type; -+ } -+ -+ /** -+ * Gets the cooldown in ticks. -+ * -+ * @return cooldown in ticks -+ */ -+ public int getCooldown() { -+ return cooldown; -+ } -+ -+ /** -+ * Sets the cooldown of the material in ticks. -+ * Setting the cooldown to 0 results in removing an already existing cooldown for the material. -+ * -+ * @param cooldown cooldown in ticks, has to be a positive number -+ */ -+ public void setCooldown(int cooldown) { -+ Preconditions.checkArgument(cooldown >= 0, "The cooldown has to be equal to or greater than 0!"); -+ this.cooldown = cooldown; -+ } -+ -+ @Override -+ public boolean isCancelled() { -+ return cancelled; -+ } -+ -+ @Override -+ public void setCancelled(boolean cancel) { -+ cancelled = cancel; -+ } -+ -+ @Override -+ @NotNull -+ public HandlerList getHandlers() { -+ return handlers; -+ } -+ -+ @NotNull -+ public static HandlerList getHandlerList() { -+ return handlers; -+ } -+} diff --git a/patches/Purpur/patches/api/0016-Player-invulnerabilities.patch b/patches/Purpur/patches/api/0015-Player-invulnerabilities.patch similarity index 100% rename from patches/Purpur/patches/api/0016-Player-invulnerabilities.patch rename to patches/Purpur/patches/api/0015-Player-invulnerabilities.patch diff --git a/patches/Purpur/patches/api/0017-Anvil-API.patch b/patches/Purpur/patches/api/0016-Anvil-API.patch similarity index 100% rename from patches/Purpur/patches/api/0017-Anvil-API.patch rename to patches/Purpur/patches/api/0016-Anvil-API.patch diff --git a/patches/Purpur/patches/api/0018-ItemStack-convenience-methods.patch b/patches/Purpur/patches/api/0017-ItemStack-convenience-methods.patch similarity index 100% rename from patches/Purpur/patches/api/0018-ItemStack-convenience-methods.patch rename to patches/Purpur/patches/api/0017-ItemStack-convenience-methods.patch diff --git a/patches/Purpur/patches/api/0019-Phantoms-attracted-to-crystals-and-crystals-shoot-ph.patch b/patches/Purpur/patches/api/0018-Phantoms-attracted-to-crystals-and-crystals-shoot-ph.patch similarity index 100% rename from patches/Purpur/patches/api/0019-Phantoms-attracted-to-crystals-and-crystals-shoot-ph.patch rename to patches/Purpur/patches/api/0018-Phantoms-attracted-to-crystals-and-crystals-shoot-ph.patch diff --git a/patches/Purpur/patches/api/0020-ChatColor-conveniences.patch b/patches/Purpur/patches/api/0019-ChatColor-conveniences.patch similarity index 100% rename from patches/Purpur/patches/api/0020-ChatColor-conveniences.patch rename to patches/Purpur/patches/api/0019-ChatColor-conveniences.patch diff --git a/patches/Purpur/patches/api/0021-Ridables.patch b/patches/Purpur/patches/api/0020-Ridables.patch similarity index 100% rename from patches/Purpur/patches/api/0021-Ridables.patch rename to patches/Purpur/patches/api/0020-Ridables.patch diff --git a/patches/Purpur/patches/api/0022-Configurable-permission-message-upgrades.patch b/patches/Purpur/patches/api/0021-Configurable-permission-message-upgrades.patch similarity index 100% rename from patches/Purpur/patches/api/0022-Configurable-permission-message-upgrades.patch rename to patches/Purpur/patches/api/0021-Configurable-permission-message-upgrades.patch diff --git a/patches/Purpur/patches/api/0023-LivingEntity-broadcastItemBreak.patch b/patches/Purpur/patches/api/0022-LivingEntity-broadcastItemBreak.patch similarity index 100% rename from patches/Purpur/patches/api/0023-LivingEntity-broadcastItemBreak.patch rename to patches/Purpur/patches/api/0022-LivingEntity-broadcastItemBreak.patch diff --git a/patches/Purpur/patches/api/0024-Item-entity-immunities.patch b/patches/Purpur/patches/api/0023-Item-entity-immunities.patch similarity index 100% rename from patches/Purpur/patches/api/0024-Item-entity-immunities.patch rename to patches/Purpur/patches/api/0023-Item-entity-immunities.patch diff --git a/patches/Purpur/patches/api/0025-Spigot-Improve-output-of-plugins-command.patch b/patches/Purpur/patches/api/0024-Spigot-Improve-output-of-plugins-command.patch similarity index 100% rename from patches/Purpur/patches/api/0025-Spigot-Improve-output-of-plugins-command.patch rename to patches/Purpur/patches/api/0024-Spigot-Improve-output-of-plugins-command.patch diff --git a/patches/Purpur/patches/api/0026-Add-option-to-disable-zombie-aggressiveness-towards-.patch b/patches/Purpur/patches/api/0025-Add-option-to-disable-zombie-aggressiveness-towards-.patch similarity index 100% rename from patches/Purpur/patches/api/0026-Add-option-to-disable-zombie-aggressiveness-towards-.patch rename to patches/Purpur/patches/api/0025-Add-option-to-disable-zombie-aggressiveness-towards-.patch diff --git a/patches/Purpur/patches/api/0027-Add-predicate-to-recipe-s-ExactChoice-ingredient.patch b/patches/Purpur/patches/api/0026-Add-predicate-to-recipe-s-ExactChoice-ingredient.patch similarity index 100% rename from patches/Purpur/patches/api/0027-Add-predicate-to-recipe-s-ExactChoice-ingredient.patch rename to patches/Purpur/patches/api/0026-Add-predicate-to-recipe-s-ExactChoice-ingredient.patch diff --git a/patches/Purpur/patches/api/0028-Add-critical-hit-check-to-EntityDamagedByEntityEvent.patch b/patches/Purpur/patches/api/0027-Add-critical-hit-check-to-EntityDamagedByEntityEvent.patch similarity index 100% rename from patches/Purpur/patches/api/0028-Add-critical-hit-check-to-EntityDamagedByEntityEvent.patch rename to patches/Purpur/patches/api/0027-Add-critical-hit-check-to-EntityDamagedByEntityEvent.patch diff --git a/patches/Purpur/patches/api/0029-Left-handed-API.patch b/patches/Purpur/patches/api/0028-Left-handed-API.patch similarity index 100% rename from patches/Purpur/patches/api/0029-Left-handed-API.patch rename to patches/Purpur/patches/api/0028-Left-handed-API.patch diff --git a/patches/Purpur/patches/api/0030-Alphabetize-in-game-plugins-list.patch b/patches/Purpur/patches/api/0029-Alphabetize-in-game-plugins-list.patch similarity index 100% rename from patches/Purpur/patches/api/0030-Alphabetize-in-game-plugins-list.patch rename to patches/Purpur/patches/api/0029-Alphabetize-in-game-plugins-list.patch diff --git a/patches/Purpur/patches/api/0031-Rabid-Wolf-API.patch b/patches/Purpur/patches/api/0030-Rabid-Wolf-API.patch similarity index 100% rename from patches/Purpur/patches/api/0031-Rabid-Wolf-API.patch rename to patches/Purpur/patches/api/0030-Rabid-Wolf-API.patch diff --git a/patches/Purpur/patches/api/0032-Fix-javadoc-warnings-missing-param-and-return.patch b/patches/Purpur/patches/api/0031-Fix-javadoc-warnings-missing-param-and-return.patch similarity index 100% rename from patches/Purpur/patches/api/0032-Fix-javadoc-warnings-missing-param-and-return.patch rename to patches/Purpur/patches/api/0031-Fix-javadoc-warnings-missing-param-and-return.patch diff --git a/patches/Purpur/patches/api/0033-PlayerBookTooLargeEvent.patch b/patches/Purpur/patches/api/0032-PlayerBookTooLargeEvent.patch similarity index 100% rename from patches/Purpur/patches/api/0033-PlayerBookTooLargeEvent.patch rename to patches/Purpur/patches/api/0032-PlayerBookTooLargeEvent.patch diff --git a/patches/Purpur/patches/api/0034-Full-netherite-armor-grants-fire-resistance.patch b/patches/Purpur/patches/api/0033-Full-netherite-armor-grants-fire-resistance.patch similarity index 100% rename from patches/Purpur/patches/api/0034-Full-netherite-armor-grants-fire-resistance.patch rename to patches/Purpur/patches/api/0033-Full-netherite-armor-grants-fire-resistance.patch diff --git a/patches/Purpur/patches/api/0035-Add-EntityTeleportHinderedEvent.patch b/patches/Purpur/patches/api/0034-Add-EntityTeleportHinderedEvent.patch similarity index 100% rename from patches/Purpur/patches/api/0035-Add-EntityTeleportHinderedEvent.patch rename to patches/Purpur/patches/api/0034-Add-EntityTeleportHinderedEvent.patch diff --git a/patches/Purpur/patches/api/0036-Add-StructureGenerateEvent.patch b/patches/Purpur/patches/api/0035-Add-StructureGenerateEvent.patch similarity index 100% rename from patches/Purpur/patches/api/0036-Add-StructureGenerateEvent.patch rename to patches/Purpur/patches/api/0035-Add-StructureGenerateEvent.patch diff --git a/patches/Purpur/patches/api/0037-Add-unsafe-Entity-serialization-API.patch b/patches/Purpur/patches/api/0036-Add-unsafe-Entity-serialization-API.patch similarity index 100% rename from patches/Purpur/patches/api/0037-Add-unsafe-Entity-serialization-API.patch rename to patches/Purpur/patches/api/0036-Add-unsafe-Entity-serialization-API.patch diff --git a/patches/Purpur/patches/server/0002-Purpur-config-files.patch b/patches/Purpur/patches/server/0002-Purpur-config-files.patch index 04f21fc3..800b36a7 100644 --- a/patches/Purpur/patches/server/0002-Purpur-config-files.patch +++ b/patches/Purpur/patches/server/0002-Purpur-config-files.patch @@ -78,7 +78,7 @@ index de9ea6770b8afc5e1020bef04ac6cca93b6b420c..21d0570a59240e955ff148bac0226b22 if (this.bF) { this.bF = false; diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index 93c0c3376c3cb2fe416c8ae3e740ffda5f985b78..226b5cd399449ca3587964221765e4d241dfc739 100644 +index 970c1be5477a01ab9c6d79e84c519e22775564ff..ee1d5e2dc9fb21190a73e0f333e962a19264dd56 100644 --- a/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java @@ -95,6 +95,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable { @@ -89,7 +89,7 @@ index 93c0c3376c3cb2fe416c8ae3e740ffda5f985b78..226b5cd399449ca3587964221765e4d2 public final co.aikar.timings.WorldTimingsHandler timings; // Paper public static BlockPosition lastPhysicsProblem; // Spigot -@@ -154,8 +155,9 @@ public abstract class World implements GeneratorAccess, AutoCloseable { +@@ -185,8 +186,9 @@ public abstract class World implements GeneratorAccess, AutoCloseable { protected World(WorldDataMutable worlddatamutable, ResourceKey resourcekey, final DimensionManager dimensionmanager, Supplier supplier, boolean flag, boolean flag1, long i, org.bukkit.generator.ChunkGenerator gen, org.bukkit.World.Environment env, java.util.concurrent.Executor executor) { // Paper this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((WorldDataServer) worlddatamutable).getName()); // Spigot this.paperConfig = new com.destroystokyo.paper.PaperWorldConfig(((WorldDataServer) worlddatamutable).getName(), this.spigotConfig); // Paper diff --git a/patches/Purpur/patches/server/0008-AFK-API.patch b/patches/Purpur/patches/server/0008-AFK-API.patch index 75e6e300..55882e7b 100644 --- a/patches/Purpur/patches/server/0008-AFK-API.patch +++ b/patches/Purpur/patches/server/0008-AFK-API.patch @@ -84,7 +84,7 @@ index 173a210392d71cdfc551f095dc0d9c9040d22d3f..7d7a512ad752e15fbe0edce47da1da76 return this.serverStatisticManager; } diff --git a/src/main/java/net/minecraft/server/IEntityAccess.java b/src/main/java/net/minecraft/server/IEntityAccess.java -index 93f2ac996904ddefed04704e554209d047faa59f..b1a546c9ef91169591ed5a71ac1c97dbc84afc03 100644 +index ad286848ddb7803640ef7eeea46b58473dd1d0c4..2e514b8291a544a88667fbca2389bde4c2ecb109 100644 --- a/src/main/java/net/minecraft/server/IEntityAccess.java +++ b/src/main/java/net/minecraft/server/IEntityAccess.java @@ -174,28 +174,18 @@ public interface IEntityAccess { @@ -193,10 +193,10 @@ index 4185ec46435ddf48d9e25c4d71ac4e14eb6301cf..1d810a9b23d236493db121dde92c7ebc if (from.getX() != Double.MAX_VALUE) { Location oldTo = to.clone(); diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index 9a8a1e05a60bca77adc904017ae70ef5f629df0b..cc1182be1f9b01ab5d8e2499f7f15ad8798de3d3 100644 +index d2b50cdc43c737d9fdfdcd7838de24cbca2017e4..9759e5cba57d14c15f78f12985a516131800d004 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java -@@ -790,7 +790,7 @@ public class WorldServer extends World implements GeneratorAccessSeed { +@@ -887,7 +887,7 @@ public class WorldServer extends World implements GeneratorAccessSeed { // CraftBukkit end if (this.everyoneSleeping && this.players.stream().noneMatch((entityplayer) -> { @@ -205,7 +205,7 @@ index 9a8a1e05a60bca77adc904017ae70ef5f629df0b..cc1182be1f9b01ab5d8e2499f7f15ad8 })) { // CraftBukkit start long l = this.worldData.getDayTime() + 24000L; -@@ -1127,7 +1127,7 @@ public class WorldServer extends World implements GeneratorAccessSeed { +@@ -1224,7 +1224,7 @@ public class WorldServer extends World implements GeneratorAccessSeed { while (iterator.hasNext()) { EntityPlayer entityplayer = (EntityPlayer) iterator.next(); diff --git a/patches/Purpur/patches/server/0025-Giants-AI-settings.patch b/patches/Purpur/patches/server/0025-Giants-AI-settings.patch index 961eae29..f8609b98 100644 --- a/patches/Purpur/patches/server/0025-Giants-AI-settings.patch +++ b/patches/Purpur/patches/server/0025-Giants-AI-settings.patch @@ -98,7 +98,7 @@ index 9f4f56c47ecd4b35ebf33ca0bf9a040074ababf2..565c938d879940d8e12fe320ea8524d2 } } diff --git a/src/main/java/net/minecraft/server/EntityInsentient.java b/src/main/java/net/minecraft/server/EntityInsentient.java -index 8a5e2806e68e5f4431fd9563fae780861e87632f..3936741bb8c1b3ad766d651e4bb8c9f5ddbe4f08 100644 +index a47217c020d2c2a3caddafa0549dc827373798dd..07908edcaffb5ee1be8a71f3f0affb91c7e6e51b 100644 --- a/src/main/java/net/minecraft/server/EntityInsentient.java +++ b/src/main/java/net/minecraft/server/EntityInsentient.java @@ -950,6 +950,7 @@ public abstract class EntityInsentient extends EntityLiving { diff --git a/patches/Purpur/patches/server/0027-Zombie-horse-naturally-spawn.patch b/patches/Purpur/patches/server/0027-Zombie-horse-naturally-spawn.patch index b1ff8a32..af57ae6e 100644 --- a/patches/Purpur/patches/server/0027-Zombie-horse-naturally-spawn.patch +++ b/patches/Purpur/patches/server/0027-Zombie-horse-naturally-spawn.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Zombie horse naturally spawn diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index cc1182be1f9b01ab5d8e2499f7f15ad8798de3d3..30388fca6d3db797825949642d372a4091cc48c2 100644 +index 9759e5cba57d14c15f78f12985a516131800d004..76058d466cf256298ea6439fffbd8d661c159f58 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java -@@ -1004,12 +1004,18 @@ public class WorldServer extends World implements GeneratorAccessSeed { +@@ -1101,12 +1101,18 @@ public class WorldServer extends World implements GeneratorAccessSeed { boolean flag1 = this.getGameRules().getBoolean(GameRules.DO_MOB_SPAWNING) && this.random.nextDouble() < (double) difficultydamagescaler.b() * paperConfig.skeleHorseSpawnChance; // Paper if (flag1) { diff --git a/patches/Purpur/patches/server/0037-Cat-spawning-options.patch b/patches/Purpur/patches/server/0037-Cat-spawning-options.patch index e24ed8be..0c637dce 100644 --- a/patches/Purpur/patches/server/0037-Cat-spawning-options.patch +++ b/patches/Purpur/patches/server/0037-Cat-spawning-options.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Cat spawning options diff --git a/src/main/java/net/minecraft/server/IEntityAccess.java b/src/main/java/net/minecraft/server/IEntityAccess.java -index b1a546c9ef91169591ed5a71ac1c97dbc84afc03..6edff6d8ce67f64420a845e992339dadf53641f8 100644 +index 2e514b8291a544a88667fbca2389bde4c2ecb109..288105ae657ade252032aa0ac9c191a8e8ebf549 100644 --- a/src/main/java/net/minecraft/server/IEntityAccess.java +++ b/src/main/java/net/minecraft/server/IEntityAccess.java @@ -47,6 +47,7 @@ public interface IEntityAccess { diff --git a/patches/Purpur/patches/server/0059-Entities-pick-up-loot-bypass-mob-griefing-gamerule.patch b/patches/Purpur/patches/server/0059-Entities-pick-up-loot-bypass-mob-griefing-gamerule.patch index fdef6927..2378d907 100644 --- a/patches/Purpur/patches/server/0059-Entities-pick-up-loot-bypass-mob-griefing-gamerule.patch +++ b/patches/Purpur/patches/server/0059-Entities-pick-up-loot-bypass-mob-griefing-gamerule.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Entities pick up loot bypass mob-griefing gamerule diff --git a/src/main/java/net/minecraft/server/EntityInsentient.java b/src/main/java/net/minecraft/server/EntityInsentient.java -index 3936741bb8c1b3ad766d651e4bb8c9f5ddbe4f08..ac6460d261014bb4b9878c96e4b447f7a471752d 100644 +index 07908edcaffb5ee1be8a71f3f0affb91c7e6e51b..d38102bbf48dd498d80911e954e910a33d390daa 100644 --- a/src/main/java/net/minecraft/server/EntityInsentient.java +++ b/src/main/java/net/minecraft/server/EntityInsentient.java @@ -546,7 +546,7 @@ public abstract class EntityInsentient extends EntityLiving { diff --git a/patches/Purpur/patches/server/0061-Villagers-follow-emerald-blocks.patch b/patches/Purpur/patches/server/0061-Villagers-follow-emerald-blocks.patch index 183c2897..fd317600 100644 --- a/patches/Purpur/patches/server/0061-Villagers-follow-emerald-blocks.patch +++ b/patches/Purpur/patches/server/0061-Villagers-follow-emerald-blocks.patch @@ -36,10 +36,10 @@ index b2a76db173ae12bff2e8a7de411cb489fdb2e9c7..2a5eda6a7e67d0b8682a96552248ea4e private CraftMerchant craftMerchant; diff --git a/src/main/java/net/minecraft/server/EntityVillagerTrader.java b/src/main/java/net/minecraft/server/EntityVillagerTrader.java -index f1a509063c09e603140c74255a3fb901693d2cc5..74c2d89af516ffc252032d5cbd12b489ea46813e 100644 +index fa3e786cd6ef67da378a5d51583ca84a82677d8c..47a89bdd163d4690fa96f63d7a9723b3bcc9fa0b 100644 --- a/src/main/java/net/minecraft/server/EntityVillagerTrader.java +++ b/src/main/java/net/minecraft/server/EntityVillagerTrader.java -@@ -40,6 +40,7 @@ public class EntityVillagerTrader extends EntityVillagerAbstract { +@@ -41,6 +41,7 @@ public class EntityVillagerTrader extends EntityVillagerAbstract { this.goalSelector.a(1, new PathfinderGoalPanic(this, 0.5D)); this.goalSelector.a(1, new PathfinderGoalLookAtTradingPlayer(this)); this.goalSelector.a(2, new EntityVillagerTrader.a(this, 2.0D, 0.35D)); diff --git a/patches/Purpur/patches/server/0062-Allow-leashing-villagers.patch b/patches/Purpur/patches/server/0062-Allow-leashing-villagers.patch index f1cdb430..f2791c45 100644 --- a/patches/Purpur/patches/server/0062-Allow-leashing-villagers.patch +++ b/patches/Purpur/patches/server/0062-Allow-leashing-villagers.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Allow leashing villagers diff --git a/src/main/java/net/minecraft/server/EntityInsentient.java b/src/main/java/net/minecraft/server/EntityInsentient.java -index ac6460d261014bb4b9878c96e4b447f7a471752d..fe721a8aac68c07476ad44244f00dc5e1ac9c02f 100644 +index d38102bbf48dd498d80911e954e910a33d390daa..566d6a2551ffbcf4366596cab87a7239a75156c6 100644 --- a/src/main/java/net/minecraft/server/EntityInsentient.java +++ b/src/main/java/net/minecraft/server/EntityInsentient.java @@ -1147,6 +1147,7 @@ public abstract class EntityInsentient extends EntityLiving { @@ -33,10 +33,10 @@ index 1cde71b812c7721298e7addb74de01e4ea297499..e4aedb3df5d0a47b5bb9175627aa794f @Override diff --git a/src/main/java/net/minecraft/server/EntityVillagerTrader.java b/src/main/java/net/minecraft/server/EntityVillagerTrader.java -index 74c2d89af516ffc252032d5cbd12b489ea46813e..96dda6a14fd17509e9bcb72cc7e9c8532c6a036b 100644 +index 47a89bdd163d4690fa96f63d7a9723b3bcc9fa0b..298d2b6f6e352bb82f3a5a307466bb6e8f47d9d3 100644 --- a/src/main/java/net/minecraft/server/EntityVillagerTrader.java +++ b/src/main/java/net/minecraft/server/EntityVillagerTrader.java -@@ -47,6 +47,13 @@ public class EntityVillagerTrader extends EntityVillagerAbstract { +@@ -48,6 +48,13 @@ public class EntityVillagerTrader extends EntityVillagerAbstract { this.goalSelector.a(10, new PathfinderGoalLookAtPlayer(this, EntityInsentient.class, 8.0F)); } diff --git a/patches/Purpur/patches/server/0069-Dispenser-curse-of-binding-protection.patch b/patches/Purpur/patches/server/0069-Dispenser-curse-of-binding-protection.patch index a6e2a960..267c455f 100644 --- a/patches/Purpur/patches/server/0069-Dispenser-curse-of-binding-protection.patch +++ b/patches/Purpur/patches/server/0069-Dispenser-curse-of-binding-protection.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Dispenser curse of binding protection diff --git a/src/main/java/net/minecraft/server/EntityInsentient.java b/src/main/java/net/minecraft/server/EntityInsentient.java -index fe721a8aac68c07476ad44244f00dc5e1ac9c02f..21f94651fcb47103b12806d456417882e7f84dcd 100644 +index 566d6a2551ffbcf4366596cab87a7239a75156c6..9807441d53fcf4ef7aaffe3801542f5a371eb7af 100644 --- a/src/main/java/net/minecraft/server/EntityInsentient.java +++ b/src/main/java/net/minecraft/server/EntityInsentient.java @@ -996,6 +996,13 @@ public abstract class EntityInsentient extends EntityLiving { diff --git a/patches/Purpur/patches/server/0079-Add-phantom-spawning-options.patch b/patches/Purpur/patches/server/0079-Add-phantom-spawning-options.patch index 58cf5ed2..28380e4c 100644 --- a/patches/Purpur/patches/server/0079-Add-phantom-spawning-options.patch +++ b/patches/Purpur/patches/server/0079-Add-phantom-spawning-options.patch @@ -221,7 +221,7 @@ index 4e3f01bc79b6ed2a322155f29f1d0dcf298c8b82..ac1ea2f0c15bccf94f203194a5a7b10e } } diff --git a/src/main/java/net/minecraft/server/SpawnerCreature.java b/src/main/java/net/minecraft/server/SpawnerCreature.java -index 661ad8f8e67046211e001ea40d97660d7c88f8e5..ee91c33a7a2edca02caf5c71fd6429f97eac7e2d 100644 +index a77b1d61b9dcb0a2a27d7e50357eaf44c99a661e..ae17950438132c5084210252bd345517131d5a99 100644 --- a/src/main/java/net/minecraft/server/SpawnerCreature.java +++ b/src/main/java/net/minecraft/server/SpawnerCreature.java @@ -385,6 +385,7 @@ public final class SpawnerCreature { @@ -233,10 +233,10 @@ index 661ad8f8e67046211e001ea40d97660d7c88f8e5..ee91c33a7a2edca02caf5c71fd6429f9 return iblockdata.r(iblockaccess, blockposition) ? false : (iblockdata.isPowerSource() ? false : (!fluid.isEmpty() ? false : (iblockdata.a((Tag) TagsBlock.PREVENT_MOB_SPAWNING_INSIDE) ? false : !entitytypes.a(iblockdata)))); } diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index 226b5cd399449ca3587964221765e4d241dfc739..0f259913ddcf151bc0128f2591e1223a56a9e115 100644 +index ee1d5e2dc9fb21190a73e0f333e962a19264dd56..8246bdf5e686c2089397e8669cf37968ef3de80d 100644 --- a/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java -@@ -1566,6 +1566,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable { +@@ -1597,6 +1597,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable { return new DifficultyDamageScaler(this.getDifficulty(), this.getDayTime(), i, f); } diff --git a/patches/Purpur/patches/server/0082-Add-allow-water-in-end-world-option.patch b/patches/Purpur/patches/server/0082-Add-allow-water-in-end-world-option.patch index c625397d..bbf4c0fb 100644 --- a/patches/Purpur/patches/server/0082-Add-allow-water-in-end-world-option.patch +++ b/patches/Purpur/patches/server/0082-Add-allow-water-in-end-world-option.patch @@ -49,10 +49,10 @@ index 120bf8436fd82294c339add2e7bff1cda8311aea..848a185c04aa90a62e6bcc49ad68a748 return true; diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index 0f259913ddcf151bc0128f2591e1223a56a9e115..1ac2e9f373ae5b4250ff9faf726a962a739d6faf 100644 +index 8246bdf5e686c2089397e8669cf37968ef3de80d..d3b3b771640a46ce9a898f645cf50007e25ae7c2 100644 --- a/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java -@@ -1641,4 +1641,14 @@ public abstract class World implements GeneratorAccess, AutoCloseable { +@@ -1672,4 +1672,14 @@ public abstract class World implements GeneratorAccess, AutoCloseable { public final boolean isDebugWorld() { return this.debugWorld; } diff --git a/patches/Purpur/patches/server/0084-Entity-lifespan.patch b/patches/Purpur/patches/server/0084-Entity-lifespan.patch index d5afcdd8..4cd8774f 100644 --- a/patches/Purpur/patches/server/0084-Entity-lifespan.patch +++ b/patches/Purpur/patches/server/0084-Entity-lifespan.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Entity lifespan diff --git a/src/main/java/net/minecraft/server/EntityInsentient.java b/src/main/java/net/minecraft/server/EntityInsentient.java -index 21f94651fcb47103b12806d456417882e7f84dcd..fcc247e86992d1e1a94438ee4f0a70182390cc62 100644 +index 9807441d53fcf4ef7aaffe3801542f5a371eb7af..ee005e482396f8ff7e46a7ca981c843a76bdda71 100644 --- a/src/main/java/net/minecraft/server/EntityInsentient.java +++ b/src/main/java/net/minecraft/server/EntityInsentient.java @@ -54,7 +54,7 @@ public abstract class EntityInsentient extends EntityLiving { diff --git a/patches/Purpur/patches/server/0100-Add-no-tick-block-list.patch b/patches/Purpur/patches/server/0100-Add-no-tick-block-list.patch index 6444e548..33b56d99 100644 --- a/patches/Purpur/patches/server/0100-Add-no-tick-block-list.patch +++ b/patches/Purpur/patches/server/0100-Add-no-tick-block-list.patch @@ -22,10 +22,10 @@ index 829d4a7508e1656dbdc912096b7eafcf30cbb5b2..6aea156d7c7a9ca8a357aad6a6781d72 } diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index 30388fca6d3db797825949642d372a4091cc48c2..138f5c577391980f2b218b25a4251ac853bb9bad 100644 +index 76058d466cf256298ea6439fffbd8d661c159f58..dc15d19fb75cd0988235ce193ac7f03c35d713c7 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java -@@ -321,14 +321,14 @@ public class WorldServer extends World implements GeneratorAccessSeed { +@@ -418,14 +418,14 @@ public class WorldServer extends World implements GeneratorAccessSeed { // CraftBukkit end if (com.destroystokyo.paper.PaperConfig.useOptimizedTickList) { this.nextTickListBlock = new com.destroystokyo.paper.server.ticklist.PaperTickList<>(this, (block) -> { diff --git a/patches/Purpur/patches/server/0104-Ridables.patch b/patches/Purpur/patches/server/0104-Ridables.patch index 8ae326a2..180fe149 100644 --- a/patches/Purpur/patches/server/0104-Ridables.patch +++ b/patches/Purpur/patches/server/0104-Ridables.patch @@ -2201,7 +2201,7 @@ index c57bf5091430709778dc21d70c8a32819c9d6639..b0a5c36d1132e2558a1fefbd9f8dd264 this.targetSelector.a(2, (new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true)).a(300)); this.targetSelector.a(3, (new PathfinderGoalNearestAttackableTarget<>(this, EntityVillagerAbstract.class, false)).a(300)); diff --git a/src/main/java/net/minecraft/server/EntityInsentient.java b/src/main/java/net/minecraft/server/EntityInsentient.java -index fcc247e86992d1e1a94438ee4f0a70182390cc62..d9b00a24b378b74e126518da9142249d2ad62c55 100644 +index ee005e482396f8ff7e46a7ca981c843a76bdda71..b64278a8e349467305b75b2180a4a423ed49d7e4 100644 --- a/src/main/java/net/minecraft/server/EntityInsentient.java +++ b/src/main/java/net/minecraft/server/EntityInsentient.java @@ -30,7 +30,7 @@ public abstract class EntityInsentient extends EntityLiving { @@ -4379,10 +4379,10 @@ index a0bfef54c853d57c9a5c6d3f9f19591649295357..548a993a1de939396d075f9176e0d60e this.h(entityhuman); } diff --git a/src/main/java/net/minecraft/server/EntityVillagerTrader.java b/src/main/java/net/minecraft/server/EntityVillagerTrader.java -index 96dda6a14fd17509e9bcb72cc7e9c8532c6a036b..3ea66955df304fd13aac2cf9bb93ea156558ae57 100644 +index 298d2b6f6e352bb82f3a5a307466bb6e8f47d9d3..d41960088bb8bc6a7fece0ef152403c43a768dde 100644 --- a/src/main/java/net/minecraft/server/EntityVillagerTrader.java +++ b/src/main/java/net/minecraft/server/EntityVillagerTrader.java -@@ -23,6 +23,7 @@ public class EntityVillagerTrader extends EntityVillagerAbstract { +@@ -24,6 +24,7 @@ public class EntityVillagerTrader extends EntityVillagerAbstract { @Override protected void initPathfinder() { this.goalSelector.a(0, new PathfinderGoalFloat(this)); @@ -4390,7 +4390,7 @@ index 96dda6a14fd17509e9bcb72cc7e9c8532c6a036b..3ea66955df304fd13aac2cf9bb93ea15 this.goalSelector.a(0, new PathfinderGoalUseItem<>(this, PotionUtil.a(new ItemStack(Items.POTION), Potions.INVISIBILITY), SoundEffects.ENTITY_WANDERING_TRADER_DISAPPEARED, (entityvillagertrader) -> { return this.world.isNight() && !entityvillagertrader.isInvisible(); })); -@@ -48,6 +49,16 @@ public class EntityVillagerTrader extends EntityVillagerAbstract { +@@ -49,6 +50,16 @@ public class EntityVillagerTrader extends EntityVillagerAbstract { } // Purpur - start @@ -4407,7 +4407,7 @@ index 96dda6a14fd17509e9bcb72cc7e9c8532c6a036b..3ea66955df304fd13aac2cf9bb93ea15 @Override public boolean a(EntityHuman entityhuman) { return world.purpurConfig.villagerTraderCanBeLeashed && !this.isLeashed(); -@@ -75,8 +86,9 @@ public class EntityVillagerTrader extends EntityVillagerAbstract { +@@ -76,8 +87,9 @@ public class EntityVillagerTrader extends EntityVillagerAbstract { } if (this.getOffers().isEmpty()) { @@ -5028,10 +5028,10 @@ index 5af554870bcf36e47aef43b966b141b9eda6c4d5..c59305ef7dd7847e204d4c4ed79758bf return new Vec3D(this.x * d0, this.y * d1, this.z * d2); } diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index 1ac2e9f373ae5b4250ff9faf726a962a739d6faf..97cc98af100edfad82668200759a5eed8fc67558 100644 +index d3b3b771640a46ce9a898f645cf50007e25ae7c2..34e5f8b3bf1b0045856ec0d06ec6d62d0b976862 100644 --- a/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java -@@ -1650,5 +1650,10 @@ public abstract class World implements GeneratorAccess, AutoCloseable { +@@ -1681,5 +1681,10 @@ public abstract class World implements GeneratorAccess, AutoCloseable { public boolean isTheEnd() { return getWorld().getEnvironment() == org.bukkit.World.Environment.THE_END; } @@ -5043,7 +5043,7 @@ index 1ac2e9f373ae5b4250ff9faf726a962a739d6faf..97cc98af100edfad82668200759a5eed // Purpur end } diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index 138f5c577391980f2b218b25a4251ac853bb9bad..c451e71601fc48294f9161ca5ef8442d31ad96f7 100644 +index dc15d19fb75cd0988235ce193ac7f03c35d713c7..9163ee821cc91f6ceb317fb4914e0394564a821b 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java @@ -102,6 +102,7 @@ public class WorldServer extends World implements GeneratorAccessSeed { diff --git a/patches/Purpur/patches/server/0110-Allow-toggling-special-MobSpawners-per-world.patch b/patches/Purpur/patches/server/0110-Allow-toggling-special-MobSpawners-per-world.patch index 07c223f4..a17562f6 100644 --- a/patches/Purpur/patches/server/0110-Allow-toggling-special-MobSpawners-per-world.patch +++ b/patches/Purpur/patches/server/0110-Allow-toggling-special-MobSpawners-per-world.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Allow toggling special MobSpawners per world In vanilla, these are all hardcoded on for world type 0 (overworld) and hardcoded off for every other world type. Default config behaviour matches this. diff --git a/src/main/java/net/minecraft/server/MobSpawnerTrader.java b/src/main/java/net/minecraft/server/MobSpawnerTrader.java -index 8d89f51182444852062d549d23c00a93e601eb38..072ec40f751b19c2a78dfcc6e439c64358d864d3 100644 +index 341af7474690b929cfa3e35cd464bbbbacb6685e..ad00ff2bd525768e4f06631d16b912c61c8eee28 100644 --- a/src/main/java/net/minecraft/server/MobSpawnerTrader.java +++ b/src/main/java/net/minecraft/server/MobSpawnerTrader.java @@ -132,7 +132,17 @@ public class MobSpawnerTrader implements MobSpawner { @@ -29,10 +29,10 @@ index 8d89f51182444852062d549d23c00a93e601eb38..072ec40f751b19c2a78dfcc6e439c643 if (SpawnerCreature.a(EntityPositionTypes.Surface.ON_GROUND, iworldreader, blockposition2, EntityTypes.WANDERING_TRADER)) { blockposition1 = blockposition2; diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index 97cc98af100edfad82668200759a5eed8fc67558..ded92fe7c7871bae6e9741747a67636d570cdeef 100644 +index 34e5f8b3bf1b0045856ec0d06ec6d62d0b976862..d72580deaa50617b5b6a991777f4b36c138308a6 100644 --- a/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java -@@ -156,7 +156,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable { +@@ -187,7 +187,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable { this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((WorldDataServer) worlddatamutable).getName()); // Spigot this.paperConfig = new com.destroystokyo.paper.PaperWorldConfig(((WorldDataServer) worlddatamutable).getName(), this.spigotConfig); // Paper this.tuinityConfig = new com.tuinity.tuinity.config.TuinityConfig.WorldConfig(((WorldDataServer)worlddatamutable).getName()); // Tuinity - Server Config @@ -42,10 +42,10 @@ index 97cc98af100edfad82668200759a5eed8fc67558..ded92fe7c7871bae6e9741747a67636d this.generator = gen; this.world = new CraftWorld((WorldServer) this, gen, env); diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index c451e71601fc48294f9161ca5ef8442d31ad96f7..02cbbf11a2b71573f50aac6fdfaa6643c18832bf 100644 +index 9163ee821cc91f6ceb317fb4914e0394564a821b..ae3ec2eca3130943536b80bd1296eba67aa08e3c 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java -@@ -339,7 +339,24 @@ public class WorldServer extends World implements GeneratorAccessSeed { +@@ -436,7 +436,24 @@ public class WorldServer extends World implements GeneratorAccessSeed { this.L = new ObjectLinkedOpenHashSet(); this.Q = flag1; this.server = minecraftserver; diff --git a/patches/Purpur/patches/server/0120-Configurable-daylight-cycle.patch b/patches/Purpur/patches/server/0120-Configurable-daylight-cycle.patch index 626ebb0f..cc7e659b 100644 --- a/patches/Purpur/patches/server/0120-Configurable-daylight-cycle.patch +++ b/patches/Purpur/patches/server/0120-Configurable-daylight-cycle.patch @@ -18,7 +18,7 @@ index 1b9b43ee696575d986c25cafec07d863acb951a7..e837db171545ceacbc84a2b360cf0d95 public PacketPlayOutUpdateTime() {} diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index 02cbbf11a2b71573f50aac6fdfaa6643c18832bf..307794aebb4ccd4d409013ed485e6defda2149ca 100644 +index ae3ec2eca3130943536b80bd1296eba67aa08e3c..5d92398369862881d997c270671ddb6b78ed2cb4 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java @@ -94,6 +94,7 @@ public class WorldServer extends World implements GeneratorAccessSeed { @@ -29,7 +29,7 @@ index 02cbbf11a2b71573f50aac6fdfaa6643c18832bf..307794aebb4ccd4d409013ed485e6def // CraftBukkit start -@@ -388,6 +389,7 @@ public class WorldServer extends World implements GeneratorAccessSeed { +@@ -485,6 +486,7 @@ public class WorldServer extends World implements GeneratorAccessSeed { this.getServer().addWorld(this.getWorld()); // CraftBukkit this.asyncChunkTaskManager = new com.destroystokyo.paper.io.chunk.ChunkTaskManager(this); // Paper @@ -37,7 +37,7 @@ index 02cbbf11a2b71573f50aac6fdfaa6643c18832bf..307794aebb4ccd4d409013ed485e6def } // Tuinity start - optimise collision -@@ -972,7 +974,21 @@ public class WorldServer extends World implements GeneratorAccessSeed { +@@ -1069,7 +1071,21 @@ public class WorldServer extends World implements GeneratorAccessSeed { this.nextTickListBlock.nextTick(); // Paper this.nextTickListFluid.nextTick(); // Paper this.worldDataServer.u().a(this.server, i); @@ -60,7 +60,7 @@ index 02cbbf11a2b71573f50aac6fdfaa6643c18832bf..307794aebb4ccd4d409013ed485e6def this.setDayTime(this.worldData.getDayTime() + 1L); } -@@ -981,6 +997,12 @@ public class WorldServer extends World implements GeneratorAccessSeed { +@@ -1078,6 +1094,12 @@ public class WorldServer extends World implements GeneratorAccessSeed { public void setDayTime(long i) { this.worldDataServer.setDayTime(i); diff --git a/patches/Purpur/patches/server/0126-Add-adjustable-breeding-cooldown-to-config.patch b/patches/Purpur/patches/server/0126-Add-adjustable-breeding-cooldown-to-config.patch index 94d49da8..021d73b8 100644 --- a/patches/Purpur/patches/server/0126-Add-adjustable-breeding-cooldown-to-config.patch +++ b/patches/Purpur/patches/server/0126-Add-adjustable-breeding-cooldown-to-config.patch @@ -33,7 +33,7 @@ index bba343542e7e6fa83ec802d97b4c139bb210ab28..d9f9e2235d091e14e5d34bb9a3273e7f int experience = this.getRandom().nextInt(7) + 1; org.bukkit.event.entity.EntityBreedEvent entityBreedEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityBreedEvent(entityageable, this, entityanimal, entityplayer, this.breedItem, experience); diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index ded92fe7c7871bae6e9741747a67636d570cdeef..7c367fe6152c30aab3e53c8f88cceba606891c93 100644 +index d72580deaa50617b5b6a991777f4b36c138308a6..87766db4e3c2e522b738fa304a861dc0985d878a 100644 --- a/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java @@ -104,6 +104,48 @@ public abstract class World implements GeneratorAccess, AutoCloseable { @@ -85,7 +85,7 @@ index ded92fe7c7871bae6e9741747a67636d570cdeef..7c367fe6152c30aab3e53c8f88cceba6 public CraftWorld getWorld() { return this.world; -@@ -157,6 +199,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable { +@@ -188,6 +230,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable { this.paperConfig = new com.destroystokyo.paper.PaperWorldConfig(((WorldDataServer) worlddatamutable).getName(), this.spigotConfig); // Paper this.tuinityConfig = new com.tuinity.tuinity.config.TuinityConfig.WorldConfig(((WorldDataServer)worlddatamutable).getName()); // Tuinity - Server Config this.purpurConfig = new net.pl3x.purpur.PurpurWorldConfig(((WorldDataServer) worlddatamutable).getName(), env); // Purpur diff --git a/patches/Purpur/patches/server/0139-Changeable-Mob-Left-Handed-Chance.patch b/patches/Purpur/patches/server/0139-Changeable-Mob-Left-Handed-Chance.patch index fbcf338d..80917ab1 100644 --- a/patches/Purpur/patches/server/0139-Changeable-Mob-Left-Handed-Chance.patch +++ b/patches/Purpur/patches/server/0139-Changeable-Mob-Left-Handed-Chance.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Changeable Mob Left Handed Chance diff --git a/src/main/java/net/minecraft/server/EntityInsentient.java b/src/main/java/net/minecraft/server/EntityInsentient.java -index d9b00a24b378b74e126518da9142249d2ad62c55..de977e80eb6cad74cbea3a00702ef804693374f0 100644 +index b64278a8e349467305b75b2180a4a423ed49d7e4..08efc5fec023acf68da1b5931a9b5eb8c16e9fc3 100644 --- a/src/main/java/net/minecraft/server/EntityInsentient.java +++ b/src/main/java/net/minecraft/server/EntityInsentient.java @@ -1137,7 +1137,7 @@ public abstract class EntityInsentient extends EntityLiving { diff --git a/patches/Purpur/patches/server/0152-Configurable-entity-base-attributes.patch b/patches/Purpur/patches/server/0152-Configurable-entity-base-attributes.patch index ecfa014c..3cc4d309 100644 --- a/patches/Purpur/patches/server/0152-Configurable-entity-base-attributes.patch +++ b/patches/Purpur/patches/server/0152-Configurable-entity-base-attributes.patch @@ -1165,10 +1165,10 @@ index 60962553e4f374b38de82f2cd4d72cef3d956c72..eef51f8e5734b897164ca9514e7b49b2 @Override diff --git a/src/main/java/net/minecraft/server/EntityVillagerTrader.java b/src/main/java/net/minecraft/server/EntityVillagerTrader.java -index 3ea66955df304fd13aac2cf9bb93ea156558ae57..32864e522b63d5d02c73a4df9f996c2ebe1b53ad 100644 +index d41960088bb8bc6a7fece0ef152403c43a768dde..9eb9ace0f59366787bc2789ecabf7800b6d29d5c 100644 --- a/src/main/java/net/minecraft/server/EntityVillagerTrader.java +++ b/src/main/java/net/minecraft/server/EntityVillagerTrader.java -@@ -63,6 +63,11 @@ public class EntityVillagerTrader extends EntityVillagerAbstract { +@@ -64,6 +64,11 @@ public class EntityVillagerTrader extends EntityVillagerAbstract { public boolean a(EntityHuman entityhuman) { return world.purpurConfig.villagerTraderCanBeLeashed && !this.isLeashed(); } diff --git a/patches/Purpur/patches/server/0169-Toggle-for-water-sensitive-mob-damage.patch b/patches/Purpur/patches/server/0169-Toggle-for-water-sensitive-mob-damage.patch index e725d33c..d98b854b 100644 --- a/patches/Purpur/patches/server/0169-Toggle-for-water-sensitive-mob-damage.patch +++ b/patches/Purpur/patches/server/0169-Toggle-for-water-sensitive-mob-damage.patch @@ -31,7 +31,7 @@ index beee80c3d8277f2d784fb6b8a4152a871ee020b0..b884addf2ce6f1ef7394658078deb2e7 @Override diff --git a/src/main/java/net/minecraft/server/EntityInsentient.java b/src/main/java/net/minecraft/server/EntityInsentient.java -index de977e80eb6cad74cbea3a00702ef804693374f0..65841a7bb58e210f07c0afd74c2fd5b3873bdd60 100644 +index 08efc5fec023acf68da1b5931a9b5eb8c16e9fc3..d6a086f59d9df8ef7f727e6a83fa51a14995123e 100644 --- a/src/main/java/net/minecraft/server/EntityInsentient.java +++ b/src/main/java/net/minecraft/server/EntityInsentient.java @@ -786,7 +786,8 @@ public abstract class EntityInsentient extends EntityLiving { diff --git a/patches/Tuinity/patches/server/0004-Util-patch.patch b/patches/Tuinity/patches/server/0004-Util-patch.patch index 2b6ba671..ebf15922 100644 --- a/patches/Tuinity/patches/server/0004-Util-patch.patch +++ b/patches/Tuinity/patches/server/0004-Util-patch.patch @@ -2032,7 +2032,7 @@ index 1f334d63282bd5c23dc3b275a220f09e60c34537..85f60b56b5689b77ba3d9e99e29b4f73 public final boolean e() { // Paper diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java -index 96a6f4675dc10a0047b7d2ee4164d0376de36c27..a4bbf3d9520db9911a5709d8d8c60322ee2fb8e2 100644 +index 0ea1b25bf98d71c251351807fa92d4d08eb6b06e..c8c0748628e83b6396c13afe896acc16c85109b0 100644 --- a/src/main/java/net/minecraft/server/ChunkProviderServer.java +++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java @@ -112,7 +112,7 @@ public class ChunkProviderServer extends IChunkProvider { @@ -2210,7 +2210,7 @@ index 96a6f4675dc10a0047b7d2ee4164d0376de36c27..a4bbf3d9520db9911a5709d8d8c60322 public ChunkProviderServer(WorldServer worldserver, Convertable.ConversionSession convertable_conversionsession, DataFixer datafixer, DefinedStructureManager definedstructuremanager, Executor executor, ChunkGenerator chunkgenerator, int i, boolean flag, WorldLoadListener worldloadlistener, Supplier supplier) { this.world = worldserver; this.serverThreadQueue = new ChunkProviderServer.a(worldserver); -@@ -591,8 +750,8 @@ public class ChunkProviderServer extends IChunkProvider { +@@ -599,8 +758,8 @@ public class ChunkProviderServer extends IChunkProvider { return !this.a(playerchunk, k); } @@ -2349,10 +2349,10 @@ index 95dd6f2034439699399b0f51ab2b761a5747331d..c9692b3e50c503affaadd217c1660291 midTickLoadChunks(); // Paper } catch (Throwable throwable) { diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java -index 42b12ad5ba68bdf8f76704ddd970715770183de0..12a207afc263f02ba1971777fe5c30d120ba9292 100644 +index 904c6a7d0a36b57bb4f693fc4fd0dd5b17adcbac..b03865a932d341ae2fdad6c9447979fa9e95fc14 100644 --- a/src/main/java/net/minecraft/server/PlayerChunk.java +++ b/src/main/java/net/minecraft/server/PlayerChunk.java -@@ -504,6 +504,7 @@ public class PlayerChunk { +@@ -508,6 +508,7 @@ public class PlayerChunk { // Paper end - per player view distance } @@ -2360,7 +2360,7 @@ index 42b12ad5ba68bdf8f76704ddd970715770183de0..12a207afc263f02ba1971777fe5c30d1 public CompletableFuture> a(ChunkStatus chunkstatus, PlayerChunkMap playerchunkmap) { int i = chunkstatus.c(); CompletableFuture> completablefuture = (CompletableFuture) this.statusFutures.get(i); -@@ -674,6 +675,9 @@ public class PlayerChunk { +@@ -678,6 +679,9 @@ public class PlayerChunk { // Paper start - rewrite ticklistserver PlayerChunk.this.chunkMap.world.onChunkSetTicking(PlayerChunk.this.location.x, PlayerChunk.this.location.z); // Paper end - rewrite ticklistserver @@ -2370,7 +2370,7 @@ index 42b12ad5ba68bdf8f76704ddd970715770183de0..12a207afc263f02ba1971777fe5c30d1 } }); -@@ -684,6 +688,12 @@ public class PlayerChunk { +@@ -688,6 +692,12 @@ public class PlayerChunk { if (flag4 && !flag5) { this.tickingFuture.complete(PlayerChunk.UNLOADED_CHUNK); this.isTickingReady = false; // Paper - cache chunk ticking stage this.tickingFuture = PlayerChunk.UNLOADED_CHUNK_FUTURE; @@ -2383,7 +2383,7 @@ index 42b12ad5ba68bdf8f76704ddd970715770183de0..12a207afc263f02ba1971777fe5c30d1 } boolean flag6 = playerchunk_state.isAtLeast(PlayerChunk.State.ENTITY_TICKING); -@@ -701,7 +711,9 @@ public class PlayerChunk { +@@ -705,7 +715,9 @@ public class PlayerChunk { Chunk entityTickingChunk = either.left().get(); PlayerChunk.this.isEntityTickingReady = true; @@ -2394,7 +2394,7 @@ index 42b12ad5ba68bdf8f76704ddd970715770183de0..12a207afc263f02ba1971777fe5c30d1 } -@@ -713,6 +725,12 @@ public class PlayerChunk { +@@ -717,6 +729,12 @@ public class PlayerChunk { if (flag6 && !flag7) { this.entityTickingFuture.complete(PlayerChunk.UNLOADED_CHUNK); this.isEntityTickingReady = false; // Paper - cache chunk ticking stage this.entityTickingFuture = PlayerChunk.UNLOADED_CHUNK_FUTURE; @@ -2495,7 +2495,7 @@ index e21c747b6c39155c44bf30860681d67b0b29fb12..9f4f9df09968dc45878ad59f5ee45672 return voxelshape != b() && voxelshape1 != b() ? (voxelshape.isEmpty() && voxelshape1.isEmpty() ? false : !c(b(), b(voxelshape, voxelshape1, OperatorBoolean.OR), OperatorBoolean.ONLY_FIRST)) : true; } diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index 2b94c195db43d8e7fd58301a33377e87daa16e98..2abce373f7dc4223f40b900e2e2b2e1aa8f0a6bf 100644 +index cf7d94aabab600822eb5e27f38690b06456d5fcc..4183117fe3977e4f0c927b4262a4804bcb8738f6 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java @@ -55,6 +55,7 @@ import org.bukkit.event.server.MapInitializeEvent; diff --git a/patches/Tuinity/patches/server/0008-Add-soft-async-catcher.patch b/patches/Tuinity/patches/server/0008-Add-soft-async-catcher.patch index 63283569..356cb371 100644 --- a/patches/Tuinity/patches/server/0008-Add-soft-async-catcher.patch +++ b/patches/Tuinity/patches/server/0008-Add-soft-async-catcher.patch @@ -200,10 +200,10 @@ index 76f9bb728def91744910d0b680b73e753f1a2b26..84ff9cfe89defad2e907708f837d33f6 for (java.util.Iterator>>> iterator = this.tickets.long2ObjectEntrySet().fastIterator(); iterator.hasNext();) { diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java -index a4bbf3d9520db9911a5709d8d8c60322ee2fb8e2..a61a9e71c435000eab1b906026767a45c998dafa 100644 +index c8c0748628e83b6396c13afe896acc16c85109b0..4082c4f366bce1784759bda773d3d35472403ade 100644 --- a/src/main/java/net/minecraft/server/ChunkProviderServer.java +++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java -@@ -1190,6 +1190,7 @@ public class ChunkProviderServer extends IChunkProvider { +@@ -1198,6 +1198,7 @@ public class ChunkProviderServer extends IChunkProvider { @Override protected boolean executeNext() { @@ -304,7 +304,7 @@ index 8efdd9bd0827d1f6a31d5f943f986dabe7d05137..43b5fa67a6b6e778a059063390fb47d6 IBlockData iblockdata1 = oldBlock; IBlockData iblockdata2 = actualBlock; diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index 2abce373f7dc4223f40b900e2e2b2e1aa8f0a6bf..bc324860305c216c18f52f34dbf2564f61067bd5 100644 +index 4183117fe3977e4f0c927b4262a4804bcb8738f6..e285038154d83cbf0d7c0b6b8a247c11b9e20119 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java @@ -1661,6 +1661,7 @@ public class WorldServer extends World implements GeneratorAccessSeed { diff --git a/patches/Tuinity/patches/server/0014-Detail-more-information-in-watchdog-dumps.patch b/patches/Tuinity/patches/server/0014-Detail-more-information-in-watchdog-dumps.patch index 719f3bd8..4056f206 100644 --- a/patches/Tuinity/patches/server/0014-Detail-more-information-in-watchdog-dumps.patch +++ b/patches/Tuinity/patches/server/0014-Detail-more-information-in-watchdog-dumps.patch @@ -140,7 +140,7 @@ index 8c7080777b370f97e1291dfedde5b419290f39cc..7fff1b3e4eda519851b714502d33122c }); throw CancelledPacketHandleException.INSTANCE; diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index bc324860305c216c18f52f34dbf2564f61067bd5..e1fbbb47cd665193bc8aa6188524cd8a9dedbb60 100644 +index e285038154d83cbf0d7c0b6b8a247c11b9e20119..97a9a201a055520a7ab92b3ecc8987eb560bf263 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java @@ -901,7 +901,26 @@ public class WorldServer extends World implements GeneratorAccessSeed { diff --git a/patches/Tuinity/patches/server/0015-Execute-chunk-tasks-mid-tick.patch b/patches/Tuinity/patches/server/0015-Execute-chunk-tasks-mid-tick.patch index d9eae21a..2e156eeb 100644 --- a/patches/Tuinity/patches/server/0015-Execute-chunk-tasks-mid-tick.patch +++ b/patches/Tuinity/patches/server/0015-Execute-chunk-tasks-mid-tick.patch @@ -18,10 +18,10 @@ index a263cd7a0680e0cc3517f84308118eb32c487732..77df6888803093ad9527d276033f2ed7 // re-schedule eventually toTick.tickState = STATE_SCHEDULED; diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java -index a61a9e71c435000eab1b906026767a45c998dafa..722a61d290243dc60dd9b7b9ae17572040e14f14 100644 +index 4082c4f366bce1784759bda773d3d35472403ade..7bb23731b548d5344013429a7d7df13686cb2249 100644 --- a/src/main/java/net/minecraft/server/ChunkProviderServer.java +++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java -@@ -885,7 +885,7 @@ public class ChunkProviderServer extends IChunkProvider { +@@ -893,7 +893,7 @@ public class ChunkProviderServer extends IChunkProvider { this.world.getMethodProfiler().enter("purge"); this.world.timings.doChunkMap.startTiming(); // Spigot this.chunkMapDistance.purgeTickets(); @@ -30,7 +30,7 @@ index a61a9e71c435000eab1b906026767a45c998dafa..722a61d290243dc60dd9b7b9ae175720 this.tickDistanceManager(); this.world.timings.doChunkMap.stopTiming(); // Spigot this.world.getMethodProfiler().exitEnter("chunks"); -@@ -895,7 +895,7 @@ public class ChunkProviderServer extends IChunkProvider { +@@ -903,7 +903,7 @@ public class ChunkProviderServer extends IChunkProvider { this.world.timings.doChunkUnload.startTiming(); // Spigot this.world.getMethodProfiler().exitEnter("unload"); this.playerChunkMap.unloadChunks(booleansupplier); @@ -39,16 +39,25 @@ index a61a9e71c435000eab1b906026767a45c998dafa..722a61d290243dc60dd9b7b9ae175720 this.world.timings.doChunkUnload.stopTiming(); // Spigot this.world.getMethodProfiler().exit(); this.clearCache(); -@@ -996,7 +996,7 @@ public class ChunkProviderServer extends IChunkProvider { +@@ -975,6 +975,8 @@ public class ChunkProviderServer extends IChunkProvider { + // Paper end + this.world.timings.countNaturalMobs.stopTiming(); // Paper - timings + ++ int ticked = 0; // Tuinity - exec chunk tasks during world tick ++ + this.p = spawnercreature_d; + this.world.getMethodProfiler().exit(); + //List list = Lists.newArrayList(this.playerChunkMap.f()); // Paper +@@ -1004,7 +1006,7 @@ public class ChunkProviderServer extends IChunkProvider { this.world.timings.chunkTicks.startTiming(); // Spigot // Paper this.world.a(chunk, k); this.world.timings.chunkTicks.stopTiming(); // Spigot // Paper - if (chunksTicked[0]++ % 10 == 0) this.world.getMinecraftServer().midTickLoadChunks(); // Paper -+ MinecraftServer.getServer().executeMidTickTasks(); // Tuinity - exec chunk tasks during world tick ++ if ((++ticked & 1) == 0) MinecraftServer.getServer().executeMidTickTasks(); // Tuinity - exec chunk tasks during world tick } } } -@@ -1152,41 +1152,7 @@ public class ChunkProviderServer extends IChunkProvider { +@@ -1160,41 +1162,7 @@ public class ChunkProviderServer extends IChunkProvider { ChunkProviderServer.this.world.getMethodProfiler().c("runTask"); super.executeTask(runnable); } @@ -279,7 +288,7 @@ index 43b5fa67a6b6e778a059063390fb47d6a599a948..165b8e20ab090284b7c70b5cc9c0d582 // Paper start - Prevent armor stands from doing entity lookups @Override diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index e1fbbb47cd665193bc8aa6188524cd8a9dedbb60..da9172303b8acf5613b283a98bf7f6f0fe859d62 100644 +index 97a9a201a055520a7ab92b3ecc8987eb560bf263..f2e630598320f7f09ecdee5a9a548b20cc1b7877 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java @@ -297,6 +297,10 @@ public class WorldServer extends World implements GeneratorAccessSeed { diff --git a/patches/Tuinity/patches/server/0018-Consolidate-flush-calls-for-entity-tracker-packets.patch b/patches/Tuinity/patches/server/0018-Consolidate-flush-calls-for-entity-tracker-packets.patch index d5fd8840..f529b81c 100644 --- a/patches/Tuinity/patches/server/0018-Consolidate-flush-calls-for-entity-tracker-packets.patch +++ b/patches/Tuinity/patches/server/0018-Consolidate-flush-calls-for-entity-tracker-packets.patch @@ -22,10 +22,10 @@ With this change I could get all 200 on at 0ms ping. So in general this patch should reduce Netty I/O thread load. diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java -index 722a61d290243dc60dd9b7b9ae17572040e14f14..fb21da40b4ceccd521393851f533f9ed9ddcd677 100644 +index 7bb23731b548d5344013429a7d7df13686cb2249..c8c4d4f3d5a0ca6255473f3f256eeb32f18a9984 100644 --- a/src/main/java/net/minecraft/server/ChunkProviderServer.java +++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java -@@ -1012,7 +1012,25 @@ public class ChunkProviderServer extends IChunkProvider { +@@ -1022,7 +1022,25 @@ public class ChunkProviderServer extends IChunkProvider { this.world.getMethodProfiler().exit(); } diff --git a/patches/Tuinity/patches/server/0020-Make-CallbackExecutor-strict-again.patch b/patches/Tuinity/patches/server/0020-Make-CallbackExecutor-strict-again.patch index e96749ca..65a45258 100644 --- a/patches/Tuinity/patches/server/0020-Make-CallbackExecutor-strict-again.patch +++ b/patches/Tuinity/patches/server/0020-Make-CallbackExecutor-strict-again.patch @@ -19,7 +19,7 @@ This patch also reverts incorrect use(s) of the class by paper. any exception thrown from it. diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java -index fb21da40b4ceccd521393851f533f9ed9ddcd677..b4c9fed303504b6839fcbdb919f8bb7612792bbc 100644 +index c8c4d4f3d5a0ca6255473f3f256eeb32f18a9984..e1a17abda657c7eb7aee7cd0763bcb48cc8b154a 100644 --- a/src/main/java/net/minecraft/server/ChunkProviderServer.java +++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java @@ -174,9 +174,9 @@ public class ChunkProviderServer extends IChunkProvider { diff --git a/patches/Tuinity/patches/server/0025-Highly-optimise-single-and-multi-AABB-VoxelShapes-an.patch b/patches/Tuinity/patches/server/0025-Highly-optimise-single-and-multi-AABB-VoxelShapes-an.patch index 946065e4..c847c05d 100644 --- a/patches/Tuinity/patches/server/0025-Highly-optimise-single-and-multi-AABB-VoxelShapes-an.patch +++ b/patches/Tuinity/patches/server/0025-Highly-optimise-single-and-multi-AABB-VoxelShapes-an.patch @@ -1457,7 +1457,7 @@ index f011869880fedae4b69e505491e8bdbc5f51dfba..0d10d317cd0b60fc0866ae505c7fd71f return this.j.d(); } diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index da9172303b8acf5613b283a98bf7f6f0fe859d62..8e1bd6029a5230f03616d9ff00b55ab14feced3f 100644 +index f2e630598320f7f09ecdee5a9a548b20cc1b7877..74cd5d412b285469f6f77bef73e65b139179992e 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java @@ -361,6 +361,251 @@ public class WorldServer extends World implements GeneratorAccessSeed { diff --git a/patches/Tuinity/patches/server/0027-Optimise-chunk-tick-iteration.patch b/patches/Tuinity/patches/server/0027-Optimise-chunk-tick-iteration.patch index 0e672441..c567b9af 100644 --- a/patches/Tuinity/patches/server/0027-Optimise-chunk-tick-iteration.patch +++ b/patches/Tuinity/patches/server/0027-Optimise-chunk-tick-iteration.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Optimise chunk tick iteration Use a dedicated list of entity ticking chunks to reduce the cost diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java -index b4c9fed303504b6839fcbdb919f8bb7612792bbc..288d487a6f22435f9070b830451f6005149c8262 100644 +index e1a17abda657c7eb7aee7cd0763bcb48cc8b154a..8c0aed61400a89799592d3d457c1d78f0217d066 100644 --- a/src/main/java/net/minecraft/server/ChunkProviderServer.java +++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java @@ -22,6 +22,12 @@ import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; // Paper @@ -22,7 +22,7 @@ index b4c9fed303504b6839fcbdb919f8bb7612792bbc..288d487a6f22435f9070b830451f6005 public class ChunkProviderServer extends IChunkProvider { private static final List b = ChunkStatus.a(); static final List getPossibleChunkStatuses() { return ChunkProviderServer.b; } // Paper - OBFHELPER -@@ -972,19 +978,23 @@ public class ChunkProviderServer extends IChunkProvider { +@@ -982,19 +988,23 @@ public class ChunkProviderServer extends IChunkProvider { //List list = Lists.newArrayList(this.playerChunkMap.f()); // Paper //Collections.shuffle(list); // Paper // Paper - moved up @@ -54,7 +54,7 @@ index b4c9fed303504b6839fcbdb919f8bb7612792bbc..288d487a6f22435f9070b830451f6005 ChunkCoordIntPair chunkcoordintpair = playerchunk.i(); if (!this.playerChunkMap.isOutsideOfRange(playerchunk, chunkcoordintpair, false)) { // Paper - optimise isOutsideOfRange -@@ -1000,7 +1010,11 @@ public class ChunkProviderServer extends IChunkProvider { +@@ -1010,7 +1020,11 @@ public class ChunkProviderServer extends IChunkProvider { } } } diff --git a/patches/Tuinity/patches/server/0032-Rework-PlayerChunk-main-thread-checks.patch b/patches/Tuinity/patches/server/0032-Rework-PlayerChunk-main-thread-checks.patch index e9676833..ecbc49fe 100644 --- a/patches/Tuinity/patches/server/0032-Rework-PlayerChunk-main-thread-checks.patch +++ b/patches/Tuinity/patches/server/0032-Rework-PlayerChunk-main-thread-checks.patch @@ -12,10 +12,10 @@ completion (completion of the world gen future, PlayerChunkMap#b(PlayerChunk, ChunkStatus)) was detected and fixed. diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java -index 12a207afc263f02ba1971777fe5c30d120ba9292..52e586a7e193b0012c9939554376f6e8f717091e 100644 +index b03865a932d341ae2fdad6c9447979fa9e95fc14..9a321c8a0a357ca1fd47d0c7fe4fe7af17204389 100644 --- a/src/main/java/net/minecraft/server/PlayerChunk.java +++ b/src/main/java/net/minecraft/server/PlayerChunk.java -@@ -560,6 +560,7 @@ public class PlayerChunk { +@@ -564,6 +564,7 @@ public class PlayerChunk { } protected void a(PlayerChunkMap playerchunkmap) { @@ -23,7 +23,7 @@ index 12a207afc263f02ba1971777fe5c30d120ba9292..52e586a7e193b0012c9939554376f6e8 ChunkStatus chunkstatus = getChunkStatus(this.oldTicketLevel); ChunkStatus chunkstatus1 = getChunkStatus(this.ticketLevel); boolean flag = this.oldTicketLevel <= PlayerChunkMap.GOLDEN_TICKET; -@@ -569,7 +570,8 @@ public class PlayerChunk { +@@ -573,7 +574,8 @@ public class PlayerChunk { // CraftBukkit start // ChunkUnloadEvent: Called before the chunk is unloaded: isChunkLoaded is still true and chunk can still be modified by plugins. if (playerchunk_state.isAtLeast(PlayerChunk.State.BORDER) && !playerchunk_state1.isAtLeast(PlayerChunk.State.BORDER)) { @@ -33,7 +33,7 @@ index 12a207afc263f02ba1971777fe5c30d120ba9292..52e586a7e193b0012c9939554376f6e8 Chunk chunk = (Chunk)either.left().orElse(null); if (chunk != null) { playerchunkmap.callbackExecutor.execute(() -> { -@@ -634,7 +636,8 @@ public class PlayerChunk { +@@ -638,7 +640,8 @@ public class PlayerChunk { if (!flag2 && flag3) { // Paper start - cache ticking ready status int expectCreateCount = ++this.fullChunkCreateCount; @@ -43,7 +43,7 @@ index 12a207afc263f02ba1971777fe5c30d120ba9292..52e586a7e193b0012c9939554376f6e8 if (either.left().isPresent() && PlayerChunk.this.fullChunkCreateCount == expectCreateCount) { // note: Here is a very good place to add callbacks to logic waiting on this. Chunk fullChunk = either.left().get(); -@@ -665,7 +668,8 @@ public class PlayerChunk { +@@ -669,7 +672,8 @@ public class PlayerChunk { if (!flag4 && flag5) { // Paper start - cache ticking ready status @@ -53,7 +53,7 @@ index 12a207afc263f02ba1971777fe5c30d120ba9292..52e586a7e193b0012c9939554376f6e8 if (either.left().isPresent()) { // note: Here is a very good place to add callbacks to logic waiting on this. Chunk tickingChunk = either.left().get(); -@@ -705,7 +709,8 @@ public class PlayerChunk { +@@ -709,7 +713,8 @@ public class PlayerChunk { } // Paper start - cache ticking ready status @@ -63,7 +63,7 @@ index 12a207afc263f02ba1971777fe5c30d120ba9292..52e586a7e193b0012c9939554376f6e8 if (either.left().isPresent()) { // note: Here is a very good place to add callbacks to logic waiting on this. Chunk entityTickingChunk = either.left().get(); -@@ -756,7 +761,8 @@ public class PlayerChunk { +@@ -760,7 +765,8 @@ public class PlayerChunk { // CraftBukkit start // ChunkLoadEvent: Called after the chunk is loaded: isChunkLoaded returns true and chunk is ready to be modified by plugins. if (!playerchunk_state.isAtLeast(PlayerChunk.State.BORDER) && playerchunk_state1.isAtLeast(PlayerChunk.State.BORDER)) { diff --git a/patches/Tuinity/patches/server/0033-Allow-Entities-to-be-removed-from-a-world-while-tick.patch b/patches/Tuinity/patches/server/0033-Allow-Entities-to-be-removed-from-a-world-while-tick.patch index 8d64b44c..8af973df 100644 --- a/patches/Tuinity/patches/server/0033-Allow-Entities-to-be-removed-from-a-world-while-tick.patch +++ b/patches/Tuinity/patches/server/0033-Allow-Entities-to-be-removed-from-a-world-while-tick.patch @@ -9,7 +9,7 @@ issues where teleporting players across worlds while ticking. Also allows us to run mid tick while ticking entities. diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index 8e1bd6029a5230f03616d9ff00b55ab14feced3f..6e5a3467f92c29181d26c03ecf49d598d75a4633 100644 +index 74cd5d412b285469f6f77bef73e65b139179992e..1f7cb91cc4f8d77b2ed0ffbf3a6063fc127f3871 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java @@ -61,7 +61,7 @@ public class WorldServer extends World implements GeneratorAccessSeed { @@ -164,8 +164,8 @@ index 8e1bd6029a5230f03616d9ff00b55ab14feced3f..6e5a3467f92c29181d26c03ecf49d598 + try { // Tuinity end while (iterator.hasNext()) { - NavigationAbstract navigationabstract = (NavigationAbstract) iterator.next(); -@@ -1951,6 +1964,9 @@ public class WorldServer extends World implements GeneratorAccessSeed { + // CraftBukkit start - fix SPIGOT-6362 +@@ -1962,6 +1975,9 @@ public class WorldServer extends World implements GeneratorAccessSeed { navigationabstract.b(blockposition); } } diff --git a/patches/Tuinity/patches/server/0034-Prevent-unload-calls-removing-tickets-for-sync-loads.patch b/patches/Tuinity/patches/server/0034-Prevent-unload-calls-removing-tickets-for-sync-loads.patch index ecc48aac..e8900d49 100644 --- a/patches/Tuinity/patches/server/0034-Prevent-unload-calls-removing-tickets-for-sync-loads.patch +++ b/patches/Tuinity/patches/server/0034-Prevent-unload-calls-removing-tickets-for-sync-loads.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Prevent unload() calls removing tickets for sync loads diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java -index 288d487a6f22435f9070b830451f6005149c8262..d4cb3850178576fe4605502ff12351b16fa98d16 100644 +index 8c0aed61400a89799592d3d457c1d78f0217d066..99f618cc9fbde5bd96cd7e6a7601d0f65d2d842f 100644 --- a/src/main/java/net/minecraft/server/ChunkProviderServer.java +++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java -@@ -701,6 +701,8 @@ public class ChunkProviderServer extends IChunkProvider { +@@ -709,6 +709,8 @@ public class ChunkProviderServer extends IChunkProvider { Arrays.fill(this.cacheChunk, (Object) null); } @@ -17,7 +17,7 @@ index 288d487a6f22435f9070b830451f6005149c8262..d4cb3850178576fe4605502ff12351b1 private CompletableFuture> getChunkFutureMainThread(int i, int j, ChunkStatus chunkstatus, boolean flag) { // Paper start - add isUrgent - old sig left in place for dirty nms plugins return getChunkFutureMainThread(i, j, chunkstatus, flag, false); -@@ -719,9 +721,12 @@ public class ChunkProviderServer extends IChunkProvider { +@@ -727,9 +729,12 @@ public class ChunkProviderServer extends IChunkProvider { PlayerChunk.State currentChunkState = PlayerChunk.getChunkState(playerchunk.getTicketLevel()); currentlyUnloading = (oldChunkState.isAtLeast(PlayerChunk.State.BORDER) && !currentChunkState.isAtLeast(PlayerChunk.State.BORDER)); } @@ -30,7 +30,7 @@ index 288d487a6f22435f9070b830451f6005149c8262..d4cb3850178576fe4605502ff12351b1 if (isUrgent) this.chunkMapDistance.markUrgent(chunkcoordintpair); // Paper if (this.a(playerchunk, l)) { GameProfilerFiller gameprofilerfiller = this.world.getMethodProfiler(); -@@ -732,12 +737,20 @@ public class ChunkProviderServer extends IChunkProvider { +@@ -740,12 +745,20 @@ public class ChunkProviderServer extends IChunkProvider { playerchunk = this.getChunk(k); gameprofilerfiller.exit(); if (this.a(playerchunk, l)) { diff --git a/patches/Tuinity/patches/server/0038-Distance-manager-tick-timings.patch b/patches/Tuinity/patches/server/0038-Distance-manager-tick-timings.patch index 1dfbb8cf..438d49ce 100644 --- a/patches/Tuinity/patches/server/0038-Distance-manager-tick-timings.patch +++ b/patches/Tuinity/patches/server/0038-Distance-manager-tick-timings.patch @@ -19,10 +19,10 @@ index 7991c66a8fe7ee9725ab75fb80d1363cd7348532..68ab5ccb2fcfe1de0503c9336572f28e private static final Map, String> taskNameCache = new MapMaker().weakKeys().makeMap(); diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java -index d4cb3850178576fe4605502ff12351b16fa98d16..c1759c5e60d5e863c57a866188500b5f1e0dd63f 100644 +index 99f618cc9fbde5bd96cd7e6a7601d0f65d2d842f..0e5e7a321dc7066444d92387968a7c41cb3a8470 100644 --- a/src/main/java/net/minecraft/server/ChunkProviderServer.java +++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java -@@ -807,6 +807,7 @@ public class ChunkProviderServer extends IChunkProvider { +@@ -815,6 +815,7 @@ public class ChunkProviderServer extends IChunkProvider { public boolean tickDistanceManager() { // Paper - private -> public if (chunkMapDistance.delayDistanceManagerTick) return false; // Paper @@ -30,7 +30,7 @@ index d4cb3850178576fe4605502ff12351b16fa98d16..c1759c5e60d5e863c57a866188500b5f boolean flag = this.chunkMapDistance.a(this.playerChunkMap); boolean flag1 = this.playerChunkMap.b(); -@@ -816,6 +817,7 @@ public class ChunkProviderServer extends IChunkProvider { +@@ -824,6 +825,7 @@ public class ChunkProviderServer extends IChunkProvider { this.clearCache(); return true; } diff --git a/patches/Tuinity/patches/server/0041-Range-check-flag-dirty-calls-in-PlayerChunk.patch b/patches/Tuinity/patches/server/0041-Range-check-flag-dirty-calls-in-PlayerChunk.patch index c4f70e71..bee9fd2d 100644 --- a/patches/Tuinity/patches/server/0041-Range-check-flag-dirty-calls-in-PlayerChunk.patch +++ b/patches/Tuinity/patches/server/0041-Range-check-flag-dirty-calls-in-PlayerChunk.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Range check flag dirty calls in PlayerChunk Simply return. diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java -index 52e586a7e193b0012c9939554376f6e8f717091e..a072208bcd92ffa9ed47757de291b82be2e71e8e 100644 +index 9a321c8a0a357ca1fd47d0c7fe4fe7af17204389..48976b1f07aeb0d588d0856f18b6fd07b2d18e05 100644 --- a/src/main/java/net/minecraft/server/PlayerChunk.java +++ b/src/main/java/net/minecraft/server/PlayerChunk.java -@@ -362,7 +362,7 @@ public class PlayerChunk { +@@ -366,7 +366,7 @@ public class PlayerChunk { if (!blockposition.isValidLocation()) return; // Paper - SPIGOT-6086 for all invalid locations; avoid acquiring locks Chunk chunk = this.getSendingChunk(); // Paper - no-tick view distance @@ -18,7 +18,7 @@ index 52e586a7e193b0012c9939554376f6e8f717091e..a072208bcd92ffa9ed47757de291b82b byte b0 = (byte) SectionPosition.a(blockposition.getY()); if (b0 < 0 || b0 >= this.dirtyBlocks.length) return; // CraftBukkit - SPIGOT-6086, SPIGOT-6296 -@@ -421,7 +421,7 @@ public class PlayerChunk { +@@ -425,7 +425,7 @@ public class PlayerChunk { this.a(world, blockposition, iblockdata); } else { ChunkSection chunksection = chunk.getSections()[sectionposition.getY()]; diff --git a/patches/Tuinity/patches/server/0043-Do-not-allow-ticket-level-changes-while-unloading-pl.patch b/patches/Tuinity/patches/server/0043-Do-not-allow-ticket-level-changes-while-unloading-pl.patch index 50425211..76b949a3 100644 --- a/patches/Tuinity/patches/server/0043-Do-not-allow-ticket-level-changes-while-unloading-pl.patch +++ b/patches/Tuinity/patches/server/0043-Do-not-allow-ticket-level-changes-while-unloading-pl.patch @@ -8,10 +8,10 @@ Sync loading the chunk at this stage would cause it to load older data, as well as screwing our region state. diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java -index c1759c5e60d5e863c57a866188500b5f1e0dd63f..0145f33f66f68a3cf03eae2128aaaa026ddc9951 100644 +index 0e5e7a321dc7066444d92387968a7c41cb3a8470..ce0bb4d228a73d8353d67828529879e1c99682f9 100644 --- a/src/main/java/net/minecraft/server/ChunkProviderServer.java +++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java -@@ -807,6 +807,7 @@ public class ChunkProviderServer extends IChunkProvider { +@@ -815,6 +815,7 @@ public class ChunkProviderServer extends IChunkProvider { public boolean tickDistanceManager() { // Paper - private -> public if (chunkMapDistance.delayDistanceManagerTick) return false; // Paper diff --git a/patches/Tuinity/patches/server/0046-Optimise-closest-entity-lookup-used-by-AI-goals.patch b/patches/Tuinity/patches/server/0046-Optimise-closest-entity-lookup-used-by-AI-goals.patch deleted file mode 100644 index 7e65a485..00000000 --- a/patches/Tuinity/patches/server/0046-Optimise-closest-entity-lookup-used-by-AI-goals.patch +++ /dev/null @@ -1,472 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Spottedleaf -Date: Thu, 27 Aug 2020 09:40:16 -0700 -Subject: [PATCH] Optimise closest entity lookup used by AI goals - -Use a special entity slice for tracking entities by class as well -as counts per chunk. This should reduce the number of entities searched. - -diff --git a/src/main/java/com/tuinity/tuinity/chunk/ChunkEntitiesByClass.java b/src/main/java/com/tuinity/tuinity/chunk/ChunkEntitiesByClass.java -new file mode 100644 -index 0000000000000000000000000000000000000000..37428f4b9ae45175fda545e9d8b55cf8a3b8c87b ---- /dev/null -+++ b/src/main/java/com/tuinity/tuinity/chunk/ChunkEntitiesByClass.java -@@ -0,0 +1,186 @@ -+package com.tuinity.tuinity.chunk; -+ -+import com.destroystokyo.paper.util.maplist.EntityList; -+import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap; -+import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap; -+import net.minecraft.server.AxisAlignedBB; -+import net.minecraft.server.Chunk; -+import net.minecraft.server.Entity; -+import net.minecraft.server.MathHelper; -+import org.spigotmc.AsyncCatcher; -+import java.util.ArrayList; -+import java.util.List; -+import java.util.function.Predicate; -+ -+public final class ChunkEntitiesByClass { -+ -+ // this class attempts to restore the original intent of nms.EntitySlice and improve upon it: -+ // fast lookups for specific entity types in a chunk. However vanilla does not track things on a -+ // chunk-wide basis, which is very important to our optimisations here: we want to eliminate chunks -+ // before searching multiple slices. We also want to maintain only lists that we need to maintain for memory purposes: -+ // so we have no choice but to lazily initialise mappings of class -> entity. -+ // Typically these are used for entity AI lookups, which means we take a heavy initial cost but ultimately win -+ // since AI lookups happen a lot. -+ -+ // This optimisation is only half of the battle with entity AI, we need to be smarter about picking the closest entity. -+ // See World#getClosestEntity -+ -+ // aggressively high load factors for each map here + fastutil collections: we want the smallest memory footprint -+ private final ExposedReference2IntOpenHashMap> chunkWideCount = new ExposedReference2IntOpenHashMap<>(4, 0.9f); -+ { -+ this.chunkWideCount.defaultReturnValue(Integer.MIN_VALUE); -+ } -+ private final Reference2ObjectOpenHashMap, ArrayList>[] slices = new Reference2ObjectOpenHashMap[16]; -+ private final Chunk chunk; -+ -+ public ChunkEntitiesByClass(final Chunk chunk) { -+ this.chunk = chunk; -+ } -+ -+ public boolean hasEntitiesMaybe(final Class clazz) { -+ final int count = this.chunkWideCount.getInt(clazz); -+ return count == Integer.MIN_VALUE || count > 0; -+ } -+ -+ public void addEntity(final Entity entity, final int sectionY) { -+ AsyncCatcher.catchOp("Add entity call"); -+ if (this.chunkWideCount.isEmpty()) { -+ return; -+ } -+ -+ final Object[] keys = this.chunkWideCount.getKey(); -+ final int[] values = this.chunkWideCount.getValue(); -+ -+ Reference2ObjectOpenHashMap, ArrayList> slice = this.slices[sectionY]; -+ if (slice == null) { -+ slice = this.slices[sectionY] = new Reference2ObjectOpenHashMap<>(4, 0.9f); -+ } -+ -+ for (int i = 0, len = keys.length; i < len; ++i) { -+ final Object _key = keys[i]; -+ if (!(_key instanceof Class)) { -+ continue; -+ } -+ final Class key = (Class)_key; -+ if (key.isInstance(entity)) { -+ ++values[i]; -+ slice.computeIfAbsent(key, (keyInMap) -> { -+ return new ArrayList<>(); -+ }).add(entity); -+ } -+ } -+ } -+ -+ public void removeEntity(final Entity entity, final int sectionY) { -+ AsyncCatcher.catchOp("Remove entity call"); -+ if (this.chunkWideCount.isEmpty()) { -+ return; -+ } -+ -+ final Object[] keys = this.chunkWideCount.getKey(); -+ final int[] values = this.chunkWideCount.getValue(); -+ -+ Reference2ObjectOpenHashMap, ArrayList> slice = this.slices[sectionY]; -+ if (slice == null) { -+ return; // seriously brain damaged plugins -+ } -+ -+ for (int i = 0, len = keys.length; i < len; ++i) { -+ final Object _key = keys[i]; -+ if (!(_key instanceof Class)) { -+ continue; -+ } -+ final Class key = (Class)_key; -+ if (key.isInstance(entity)) { -+ --values[i]; -+ final ArrayList list = slice.get(key); -+ if (list == null) { -+ return; // seriously brain damaged plugins -+ } -+ list.remove(entity); -+ } -+ } -+ } -+ -+ -+ private void computeClass(final Class clazz) { -+ AsyncCatcher.catchOp("Entity class compute call"); -+ int totalCount = 0; -+ -+ EntityList entityList = this.chunk.entities; -+ Entity[] entities = entityList.getRawData(); -+ for (int i = 0, len = entityList.size(); i < len; ++i) { -+ final Entity entity = entities[i]; -+ -+ if (clazz.isInstance(entity)) { -+ ++totalCount; -+ Reference2ObjectOpenHashMap, ArrayList> slice = this.slices[entity.chunkY]; -+ if (slice == null) { -+ slice = this.slices[entity.chunkY] = new Reference2ObjectOpenHashMap<>(4, 0.9f); -+ } -+ slice.computeIfAbsent(clazz, (keyInMap) -> { -+ return new ArrayList<>(); -+ }).add(entity); -+ } -+ } -+ -+ this.chunkWideCount.put(clazz, totalCount); -+ } -+ -+ public void lookupClass(final Class clazz, final Entity entity, final AxisAlignedBB boundingBox, final Predicate predicate, final List into) { -+ final int count = this.chunkWideCount.getInt(clazz); -+ if (count == Integer.MIN_VALUE) { -+ this.computeClass(clazz); -+ if (this.chunkWideCount.getInt(clazz) <= 0) { -+ return; -+ } -+ } else if (count <= 0) { -+ return; -+ } -+ -+ // copied from getEntities -+ int min = MathHelper.floor((boundingBox.minY - 2.0D) / 16.0D); -+ int max = MathHelper.floor((boundingBox.maxY + 2.0D) / 16.0D); -+ -+ min = MathHelper.clamp(min, 0, this.slices.length - 1); -+ max = MathHelper.clamp(max, 0, this.slices.length - 1); -+ -+ for (int y = min; y <= max; ++y) { -+ final Reference2ObjectOpenHashMap, ArrayList> slice = this.slices[y]; -+ if (slice == null) { -+ continue; -+ } -+ -+ final ArrayList entities = slice.get(clazz); -+ if (entities == null) { -+ continue; -+ } -+ -+ for (int i = 0, len = entities.size(); i < len; ++i) { -+ Entity entity1 = entities.get(i); -+ if (entity1.shouldBeRemoved) continue; // Paper -+ -+ if (entity1 != entity && entity1.getBoundingBox().intersects(boundingBox)) { -+ if (predicate == null || predicate.test(entity1)) { -+ into.add(entity1); -+ } -+ } -+ } -+ } -+ } -+ -+ static final class ExposedReference2IntOpenHashMap extends Reference2IntOpenHashMap { -+ -+ public ExposedReference2IntOpenHashMap(final int expected, final float loadFactor) { -+ super(expected, loadFactor); -+ } -+ -+ public Object[] getKey() { -+ return this.key; -+ } -+ -+ public int[] getValue() { -+ return this.value; -+ } -+ } -+} -diff --git a/src/main/java/com/tuinity/tuinity/util/CachedLists.java b/src/main/java/com/tuinity/tuinity/util/CachedLists.java -index 387eeb5d770ba9fe564c61df8cc92ac8b1569f61..21e50c75e0bffaa5cc5faf6aa81ae7428caca731 100644 ---- a/src/main/java/com/tuinity/tuinity/util/CachedLists.java -+++ b/src/main/java/com/tuinity/tuinity/util/CachedLists.java -@@ -1,6 +1,7 @@ - package com.tuinity.tuinity.util; - - import net.minecraft.server.AxisAlignedBB; -+import net.minecraft.server.Chunk; - import net.minecraft.server.Entity; - import org.bukkit.Bukkit; - import org.bukkit.craftbukkit.util.UnsafeList; -@@ -46,8 +47,28 @@ public class CachedLists { - tempGetEntitiesListInUse = false; - } - -+ static final UnsafeList TEMP_GET_CHUNKS_LIST = new UnsafeList<>(1024); -+ static boolean tempGetChunksListInUse; -+ -+ public static UnsafeList getTempGetChunksList() { -+ if (!Bukkit.isPrimaryThread() || tempGetChunksListInUse) { -+ return new UnsafeList<>(); -+ } -+ tempGetChunksListInUse = true; -+ return TEMP_GET_CHUNKS_LIST; -+ } -+ -+ public static void returnTempGetChunksList(List list) { -+ if (list != TEMP_GET_CHUNKS_LIST) { -+ return; -+ } -+ ((UnsafeList)list).setSize(0); -+ tempGetChunksListInUse = false; -+ } -+ - public static void reset() { - TEMP_COLLISION_LIST.completeReset(); - TEMP_GET_ENTITIES_LIST.completeReset(); -+ TEMP_GET_CHUNKS_LIST.completeReset(); - } - } -diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java -index dface62144bb230c576e9eafad1016d19d211118..cd4a36a2f0feb2df928ee5ed7f0bca6d996bad7f 100644 ---- a/src/main/java/net/minecraft/server/Chunk.java -+++ b/src/main/java/net/minecraft/server/Chunk.java -@@ -141,6 +141,22 @@ public class Chunk implements IChunkAccess { - } - // Tuinity end - optimise hard collision handling - -+ // Tuinity start - entity slices by class -+ private final com.tuinity.tuinity.chunk.ChunkEntitiesByClass entitiesByClass = new com.tuinity.tuinity.chunk.ChunkEntitiesByClass(this); -+ -+ public boolean hasEntitiesMaybe(Class clazz) { -+ return this.entitiesByClass.hasEntitiesMaybe(clazz); -+ } -+ -+ public final void getEntitiesClass(Class clazz, Entity entity, AxisAlignedBB boundingBox, Predicate predicate, List into) { -+ if (!org.bukkit.Bukkit.isPrimaryThread()) { -+ this.getEntities((Class)clazz, boundingBox, (List)into, (Predicate)predicate); -+ return; -+ } -+ this.entitiesByClass.lookupClass(clazz, entity, boundingBox, predicate, into); -+ } -+ // Tuinity end - entity slices by class -+ - public Chunk(World world, ChunkCoordIntPair chunkcoordintpair, BiomeStorage biomestorage, ChunkConverter chunkconverter, TickList ticklist, TickList ticklist1, long i, @Nullable ChunkSection[] achunksection, @Nullable Consumer consumer) { - this.sections = new ChunkSection[16]; - this.e = Maps.newHashMap(); -@@ -644,7 +660,7 @@ public class Chunk implements IChunkAccess { - entity.chunkX = this.loc.x; - entity.chunkY = k; - entity.chunkZ = this.loc.z; -- this.entities.add(entity); // Paper - per chunk entity list -+ this.entities.add(entity); this.entitiesByClass.addEntity(entity, entity.chunkY); // Paper - per chunk entity list // Tuinity - entities by class - this.entitySlices[k].add(entity); if (entity.hardCollides()) this.hardCollidingEntities[k].add(entity); // Tuinity - optimise hard colliding entities - // Paper start - if (entity instanceof EntityItem) { -@@ -683,7 +699,7 @@ public class Chunk implements IChunkAccess { - entity.entitySlice = null; - entity.inChunk = false; - } -- if (entity.hardCollides()) this.hardCollidingEntities[i].remove(entity); if (!this.entitySlices[i].remove(entity)) { // Tuinity - optimise hard colliding entities -+ if (entity.hardCollides()) this.hardCollidingEntities[i].remove(entity); this.entitiesByClass.removeEntity(entity, i); if (!this.entitySlices[i].remove(entity)) { // Tuinity - optimise hard colliding entities // Tuinity - entities by class - return; - } - if (entity instanceof EntityItem) { -@@ -996,6 +1012,7 @@ public class Chunk implements IChunkAccess { - - } - -+ public final void getEntities(Class oclass, AxisAlignedBB axisalignedbb, List list, @Nullable Predicate predicate) { this.a(oclass, axisalignedbb, list, predicate); } // Tuinity - OBFHELPER - public void a(Class oclass, AxisAlignedBB axisalignedbb, List list, @Nullable Predicate predicate) { - org.spigotmc.AsyncCatcher.catchOp("Chunk getEntities call"); // Spigot - int i = MathHelper.floor((axisalignedbb.minY - 2.0D) / 16.0D); -diff --git a/src/main/java/net/minecraft/server/IEntityAccess.java b/src/main/java/net/minecraft/server/IEntityAccess.java -index c17cbadeff9cb3ea955b9db99ab71d6d7fd8c247..93f2ac996904ddefed04704e554209d047faa59f 100644 ---- a/src/main/java/net/minecraft/server/IEntityAccess.java -+++ b/src/main/java/net/minecraft/server/IEntityAccess.java -@@ -214,12 +214,12 @@ public interface IEntityAccess { - } - - @Nullable -- default T a(Class oclass, PathfinderTargetCondition pathfindertargetcondition, @Nullable EntityLiving entityliving, double d0, double d1, double d2, AxisAlignedBB axisalignedbb) { -+ default T a(Class oclass, PathfinderTargetCondition pathfindertargetcondition, @Nullable EntityLiving entityliving, double d0, double d1, double d2, AxisAlignedBB axisalignedbb) { // Tuinity - diff on change, override in World - this should be "get closest entity by class that matches path finder target condition" - return this.a(this.a(oclass, axisalignedbb, null), pathfindertargetcondition, entityliving, d0, d1, d2); // Paper - decompile fix - } - - @Nullable -- default T b(Class oclass, PathfinderTargetCondition pathfindertargetcondition, @Nullable EntityLiving entityliving, double d0, double d1, double d2, AxisAlignedBB axisalignedbb) { -+ default T b(Class oclass, PathfinderTargetCondition pathfindertargetcondition, @Nullable EntityLiving entityliving, double d0, double d1, double d2, AxisAlignedBB axisalignedbb) { // Tuinity - diff on change, override in World - this should be "get closest entity by class that matches path finder target condition" - return this.a(this.b(oclass, axisalignedbb, null), pathfindertargetcondition, entityliving, d0, d1, d2); // Paper - decompile fix - } - -diff --git a/src/main/java/net/minecraft/server/PathfinderTargetCondition.java b/src/main/java/net/minecraft/server/PathfinderTargetCondition.java -index 253377c6238594de1f76cafcbf8223592e4d3f6b..3ebe3d0dc4c2c6aee6ea349006a74cbe5aa8e78f 100644 ---- a/src/main/java/net/minecraft/server/PathfinderTargetCondition.java -+++ b/src/main/java/net/minecraft/server/PathfinderTargetCondition.java -@@ -51,6 +51,7 @@ public class PathfinderTargetCondition { - return this; - } - -+ public final boolean test(@Nullable EntityLiving entityliving, EntityLiving entityliving1) { return this.a(entityliving, entityliving1); } // Tuinity - OBFHELPER - public boolean a(@Nullable EntityLiving entityliving, EntityLiving entityliving1) { - if (entityliving == entityliving1) { - return false; -diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index dccdbb1c218d9fd8acb81998bd5884dc4aba7c1c..1d87e7461d28d8a639fafcfdfa5496014e9180f6 100644 ---- a/src/main/java/net/minecraft/server/World.java -+++ b/src/main/java/net/minecraft/server/World.java -@@ -1186,7 +1186,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable { - Chunk chunk = (Chunk)this.getChunkIfLoadedImmediately(i1, j1); // Paper - - if (chunk != null) { -- chunk.a(oclass, axisalignedbb, list, predicate); -+ chunk.getEntitiesClass(oclass, null, axisalignedbb, (Predicate)predicate, (List)list); // Tuinity - optimise lookup by entity class - } - } - } -@@ -1209,7 +1209,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable { - Chunk chunk = (Chunk)this.getChunkIfLoadedImmediately(i1, j1); // Paper - - if (chunk != null) { -- chunk.a(oclass, axisalignedbb, list, predicate); -+ chunk.getEntitiesClass(oclass, null, axisalignedbb, (Predicate)predicate, (List)list); // Tuinity - optimise lookup by entity class - } - } - } -@@ -1217,6 +1217,106 @@ public abstract class World implements GeneratorAccess, AutoCloseable { - return list; - } - -+ // Tuinity start -+ @Override -+ public T b(Class oclass, PathfinderTargetCondition pathfindertargetcondition, @Nullable EntityLiving entityliving, double d0, double d1, double d2, AxisAlignedBB axisalignedbb) { -+ return this.getClosestEntity(oclass, pathfindertargetcondition, entityliving, d0, d1, d2, axisalignedbb); -+ } -+ -+ @Override -+ public T a(Class oclass, PathfinderTargetCondition pathfindertargetcondition, @Nullable EntityLiving entityliving, double d0, double d1, double d2, AxisAlignedBB axisalignedbb) { -+ return this.getClosestEntity(oclass, pathfindertargetcondition, entityliving, d0, d1, d2, axisalignedbb); -+ } -+ -+ public final T getClosestEntity(Class clazz, -+ PathfinderTargetCondition condition, -+ @Nullable EntityLiving source, -+ double x, double y, double z, -+ AxisAlignedBB boundingBox) { -+ org.bukkit.craftbukkit.util.UnsafeList entities = com.tuinity.tuinity.util.CachedLists.getTempGetEntitiesList(); -+ try { -+ int lowerX = MCUtil.fastFloor((boundingBox.minX - 2.0D)) >> 4; -+ int upperX = MCUtil.fastFloor((boundingBox.maxX + 2.0D)) >> 4; -+ int lowerZ = MCUtil.fastFloor((boundingBox.minZ - 2.0D)) >> 4; -+ int upperZ = MCUtil.fastFloor((boundingBox.maxZ + 2.0D)) >> 4; -+ -+ org.bukkit.craftbukkit.util.UnsafeList chunks = com.tuinity.tuinity.util.CachedLists.getTempGetChunksList(); -+ try { -+ T closest = null; -+ double closestDistance = Double.MAX_VALUE; -+ ChunkProviderServer chunkProvider = ((WorldServer)this).getChunkProvider(); -+ -+ int centerX = (lowerX + upperX) >> 1; -+ int centerZ = (lowerZ + upperZ) >> 1; -+ // Copied from MCUtil.getSpiralOutChunks -+ Chunk temp; -+ if ((temp = chunkProvider.getChunkAtIfLoadedImmediately(centerX, centerZ)) != null && temp.hasEntitiesMaybe(clazz)) { -+ chunks.add(temp); -+ } -+ int radius = Math.max((upperX - lowerX + 1) >> 1, (upperZ - lowerZ + 1) >> 1); -+ for (int r = 1; r <= radius; r++) { -+ int ox = -r; -+ int oz = r; -+ -+ // Iterates the edge of half of the box; then negates for other half. -+ while (ox <= r && oz > -r) { -+ { -+ int cx = centerX + ox; -+ int cz = centerZ + oz; -+ if (cx >= lowerX && cx <= upperX && cz >= lowerZ && cz <= upperZ && -+ (temp = chunkProvider.getChunkAtIfLoadedImmediately(cx, cz)) != null && -+ temp.hasEntitiesMaybe(clazz)) { -+ chunks.add(temp); -+ } -+ } -+ { -+ int cx = centerX - ox; -+ int cz = centerZ - oz; -+ if (cx >= lowerX && cx <= upperX && cz >= lowerZ && cz <= upperZ && -+ (temp = chunkProvider.getChunkAtIfLoadedImmediately(cx, cz)) != null && -+ temp.hasEntitiesMaybe(clazz)) { -+ chunks.add(temp); -+ } -+ } -+ -+ if (ox < r) { -+ ox++; -+ } else { -+ oz--; -+ } -+ } -+ } -+ -+ Object[] chunkData = chunks.getRawDataArray(); -+ for (int cindex = 0, clen = chunks.size(); cindex < clen; ++cindex) { -+ final Chunk chunk = (Chunk)chunkData[cindex]; -+ -+ chunk.getEntitiesClass(clazz, source, boundingBox, null, entities); -+ -+ Object[] entityData = entities.getRawDataArray(); -+ for (int eindex = 0, entities_len = entities.size(); eindex < entities_len; ++eindex) { -+ T entity = (T)entityData[eindex]; -+ double distance = entity.getDistanceSquared(x, y, z); -+ // check distance first, as it's the least expensive -+ if (distance < closestDistance && condition.test(source, entity)) { -+ closest = entity; -+ closestDistance = distance; -+ } -+ } -+ -+ entities.setSize(0); -+ } -+ -+ return closest; -+ } finally { -+ com.tuinity.tuinity.util.CachedLists.returnTempGetChunksList(chunks); -+ } -+ } finally { -+ com.tuinity.tuinity.util.CachedLists.returnTempGetEntitiesList(entities); -+ } -+ } -+ // Tuinity end -+ - @Nullable - public abstract Entity getEntity(int i); - -diff --git a/src/main/java/org/bukkit/craftbukkit/util/UnsafeList.java b/src/main/java/org/bukkit/craftbukkit/util/UnsafeList.java -index 50f855b931dba60754fff9c7cdf5e0e744f00fdd..7c0d90552eeb6de7dab174e2ba4acfc89a7b3db0 100644 ---- a/src/main/java/org/bukkit/craftbukkit/util/UnsafeList.java -+++ b/src/main/java/org/bukkit/craftbukkit/util/UnsafeList.java -@@ -35,6 +35,13 @@ public class UnsafeList extends AbstractList implements List, RandomAcc - iterPool[0] = new Itr(); - } - -+ // Tuinity start -+ @Override -+ public void sort(java.util.Comparator c) { -+ Arrays.sort((E[])this.data, 0, size, c); -+ } -+ // Tuinity end -+ - public UnsafeList(int capacity) { - this(capacity, 5); - } diff --git a/patches/Tuinity/patches/server/0046-Optimise-closest-entity-lookup.patch b/patches/Tuinity/patches/server/0046-Optimise-closest-entity-lookup.patch new file mode 100644 index 00000000..aba57425 --- /dev/null +++ b/patches/Tuinity/patches/server/0046-Optimise-closest-entity-lookup.patch @@ -0,0 +1,985 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Spottedleaf +Date: Thu, 27 Aug 2020 09:40:16 -0700 +Subject: [PATCH] Optimise closest entity lookup + +Rewrites the entity slice storage so that entity by +class lookups look through less entities in total. + +Also optimise the nearest entity by class method +used by entity AI as well. + +As a sidenote, this entity slice implementation +removes the async catchers because it has been +designed to be MT-Safe for reads off of other +threads. + +diff --git a/src/main/java/com/tuinity/tuinity/util/CachedLists.java b/src/main/java/com/tuinity/tuinity/util/CachedLists.java +index 387eeb5d770ba9fe564c61df8cc92ac8b1569f61..21e50c75e0bffaa5cc5faf6aa81ae7428caca731 100644 +--- a/src/main/java/com/tuinity/tuinity/util/CachedLists.java ++++ b/src/main/java/com/tuinity/tuinity/util/CachedLists.java +@@ -1,6 +1,7 @@ + package com.tuinity.tuinity.util; + + import net.minecraft.server.AxisAlignedBB; ++import net.minecraft.server.Chunk; + import net.minecraft.server.Entity; + import org.bukkit.Bukkit; + import org.bukkit.craftbukkit.util.UnsafeList; +@@ -46,8 +47,28 @@ public class CachedLists { + tempGetEntitiesListInUse = false; + } + ++ static final UnsafeList TEMP_GET_CHUNKS_LIST = new UnsafeList<>(1024); ++ static boolean tempGetChunksListInUse; ++ ++ public static UnsafeList getTempGetChunksList() { ++ if (!Bukkit.isPrimaryThread() || tempGetChunksListInUse) { ++ return new UnsafeList<>(); ++ } ++ tempGetChunksListInUse = true; ++ return TEMP_GET_CHUNKS_LIST; ++ } ++ ++ public static void returnTempGetChunksList(List list) { ++ if (list != TEMP_GET_CHUNKS_LIST) { ++ return; ++ } ++ ((UnsafeList)list).setSize(0); ++ tempGetChunksListInUse = false; ++ } ++ + public static void reset() { + TEMP_COLLISION_LIST.completeReset(); + TEMP_GET_ENTITIES_LIST.completeReset(); ++ TEMP_GET_CHUNKS_LIST.completeReset(); + } + } +diff --git a/src/main/java/com/tuinity/tuinity/world/ChunkEntitySlices.java b/src/main/java/com/tuinity/tuinity/world/ChunkEntitySlices.java +new file mode 100644 +index 0000000000000000000000000000000000000000..9cc14620d26d63a9e8fec7735625b22411b43e98 +--- /dev/null ++++ b/src/main/java/com/tuinity/tuinity/world/ChunkEntitySlices.java +@@ -0,0 +1,401 @@ ++package com.tuinity.tuinity.world; ++ ++import it.unimi.dsi.fastutil.objects.Reference2ObjectMap; ++import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap; ++import net.minecraft.server.AxisAlignedBB; ++import net.minecraft.server.Entity; ++import net.minecraft.server.EntityComplexPart; ++import net.minecraft.server.EntityEnderDragon; ++import net.minecraft.server.EntityTypes; ++import net.minecraft.server.MathHelper; ++import net.minecraft.server.World; ++import java.util.Arrays; ++import java.util.Iterator; ++import java.util.List; ++import java.util.function.Predicate; ++ ++public final class ChunkEntitySlices { ++ ++ private static final int RTREE_THRESHOLD = 20; ++ ++ protected final int minSection; ++ protected final int maxSection; ++ protected final int chunkX; ++ protected final int chunkZ; ++ protected final World world; ++ ++ protected final EntityCollectionBySection allEntities; ++ protected final EntityCollectionBySection hardCollidingEntities; ++ protected final Reference2ObjectOpenHashMap, EntityCollectionBySection> entitiesByClass; ++ ++ public ChunkEntitySlices(final World world, final int chunkX, final int chunkZ, ++ final int minSection, final int maxSection) { // inclusive, inclusive ++ this.minSection = minSection; ++ this.maxSection = maxSection; ++ this.chunkX = chunkX; ++ this.chunkZ = chunkZ; ++ this.world = world; ++ ++ this.allEntities = new EntityCollectionBySection(this); ++ this.hardCollidingEntities = new EntityCollectionBySection(this); ++ this.entitiesByClass = new Reference2ObjectOpenHashMap<>(); ++ } ++ ++ // synchronized is used in this class for write protection, thank you dumbass mods for doing dumb ++ // shit async. ++ ++ public synchronized void addEntity(final Entity entity, final int chunkSection) { ++ final int sectionIndex = chunkSection - this.minSection; ++ ++ this.allEntities.addEntity(entity, sectionIndex); ++ ++ if (entity.hardCollides()) { ++ this.hardCollidingEntities.addEntity(entity, sectionIndex); ++ } ++ ++ for (final Iterator, EntityCollectionBySection>> iterator = ++ this.entitiesByClass.reference2ObjectEntrySet().fastIterator(); iterator.hasNext();) { ++ final Reference2ObjectMap.Entry, EntityCollectionBySection> entry = iterator.next(); ++ ++ if (entry.getKey().isInstance(entity)) { ++ entry.getValue().addEntity(entity, sectionIndex); ++ } ++ } ++ } ++ ++ public synchronized void removeEntity(final Entity entity, final int chunkSection) { ++ final int sectionIndex = chunkSection - this.minSection; ++ ++ this.allEntities.removeEntity(entity, sectionIndex); ++ ++ if (entity.hardCollides()) { ++ this.hardCollidingEntities.removeEntity(entity, sectionIndex); ++ } ++ ++ for (final Iterator, EntityCollectionBySection>> iterator = ++ this.entitiesByClass.reference2ObjectEntrySet().fastIterator(); iterator.hasNext();) { ++ final Reference2ObjectMap.Entry, EntityCollectionBySection> entry = iterator.next(); ++ ++ if (entry.getKey().isInstance(entity)) { ++ entry.getValue().removeEntity(entity, sectionIndex); ++ } ++ } ++ } ++ ++ public void getHardCollidingEntities(final Entity except, final AxisAlignedBB box, final List into, final Predicate predicate) { ++ this.hardCollidingEntities.getEntities(except, box, into, predicate); ++ } ++ ++ public void getEntities(final Entity except, final AxisAlignedBB box, final List into, final Predicate predicate) { ++ this.allEntities.getEntitiesWithEnderDragonParts(except, box, into, predicate); ++ } ++ ++ public void getEntities(final EntityTypes type, final AxisAlignedBB box, final List into, ++ final Predicate predicate) { ++ this.allEntities.getEntities(type, box, (List)into, (Predicate)predicate); ++ } ++ ++ protected EntityCollectionBySection initClass(final Class clazz) { ++ final EntityCollectionBySection ret = new EntityCollectionBySection(this); ++ ++ for (int sectionIndex = 0; sectionIndex < this.allEntities.entitiesBySection.length; ++sectionIndex) { ++ final BasicEntityList sectionEntities = this.allEntities.entitiesBySection[sectionIndex]; ++ if (sectionEntities == null) { ++ continue; ++ } ++ ++ final Entity[] storage = sectionEntities.storage; ++ ++ for (int i = 0, len = Math.min(storage.length, sectionEntities.size()); i < len; ++i) { ++ final Entity entity = storage[i]; ++ ++ if (clazz.isInstance(entity)) { ++ ret.addEntity(entity, sectionIndex); ++ } ++ } ++ } ++ ++ return ret; ++ } ++ ++ public void getEntities(final Class clazz, final Entity except, final AxisAlignedBB box, final List into, ++ final Predicate predicate) { ++ EntityCollectionBySection collection = this.entitiesByClass.get(clazz); ++ if (collection != null) { ++ collection.getEntities(except, box, (List)into, (Predicate)predicate); ++ } else { ++ synchronized (this) { ++ this.entitiesByClass.putIfAbsent(clazz, collection = this.initClass(clazz)); ++ } ++ collection.getEntities(except, box, (List)into, (Predicate)predicate); ++ } ++ } ++ ++ public synchronized void updateEntity(final Entity entity) { ++ /*// TODO ++ if (prev aabb != entity.getBoundingBox()) { ++ this.entityMap.delete(entity, prev aabb); ++ this.entityMap.insert(entity, prev aabb = entity.getBoundingBox()); ++ }*/ ++ } ++ ++ protected static final class BasicEntityList { ++ ++ protected static final Entity[] EMPTY = new Entity[0]; ++ protected static final int DEFAULT_CAPACITY = 4; ++ ++ protected E[] storage; ++ protected int size; ++ ++ public BasicEntityList() { ++ this(0); ++ } ++ ++ public BasicEntityList(final int cap) { ++ this.storage = (E[])(cap <= 0 ? EMPTY : new Entity[cap]); ++ } ++ ++ public boolean isEmpty() { ++ return this.size == 0; ++ } ++ ++ public int size() { ++ return this.size; ++ } ++ ++ private void resize() { ++ if (this.storage == EMPTY) { ++ this.storage = (E[])new Entity[DEFAULT_CAPACITY]; ++ } else { ++ this.storage = Arrays.copyOf(this.storage, this.storage.length * 2); ++ } ++ } ++ ++ public void add(final E entity) { ++ final int idx = this.size++; ++ if (idx >= this.storage.length) { ++ this.resize(); ++ this.storage[idx] = entity; ++ } else { ++ this.storage[idx] = entity; ++ } ++ } ++ ++ public int indexOf(final E entity) { ++ final E[] storage = this.storage; ++ ++ for (int i = 0, len = Math.min(this.storage.length, this.size); i < len; ++i) { ++ if (storage[i] == entity) { ++ return i; ++ } ++ } ++ ++ return -1; ++ } ++ ++ public boolean remove(final E entity) { ++ final int idx = this.indexOf(entity); ++ if (idx == -1) { ++ return false; ++ } ++ ++ final int size = --this.size; ++ final E[] storage = this.storage; ++ if (idx != size) { ++ System.arraycopy(storage, idx + 1, storage, idx, size - idx); ++ } ++ ++ storage[size] = null; ++ ++ return true; ++ } ++ ++ public boolean has(final E entity) { ++ return this.indexOf(entity) != -1; ++ } ++ } ++ ++ protected static final class EntityCollectionBySection { ++ ++ protected final ChunkEntitySlices manager; ++ protected final long[] nonEmptyBitset; ++ protected final BasicEntityList[] entitiesBySection; ++ protected int count; ++ ++ public EntityCollectionBySection(final ChunkEntitySlices manager) { ++ this.manager = manager; ++ ++ final int sectionCount = manager.maxSection - manager.minSection + 1; ++ ++ this.nonEmptyBitset = new long[(sectionCount + (Long.SIZE - 1)) >>> 6]; // (sectionCount + (Long.SIZE - 1)) / Long.SIZE ++ this.entitiesBySection = new BasicEntityList[sectionCount]; ++ } ++ ++ public void addEntity(final Entity entity, final int sectionIndex) { ++ BasicEntityList list = this.entitiesBySection[sectionIndex]; ++ ++ if (list != null && list.has(entity)) { ++ return; ++ } ++ ++ if (list == null) { ++ this.entitiesBySection[sectionIndex] = list = new BasicEntityList<>(); ++ this.nonEmptyBitset[sectionIndex >>> 6] |= (1L << (sectionIndex & (Long.SIZE - 1))); ++ } ++ ++ list.add(entity); ++ ++this.count; ++ } ++ ++ public void removeEntity(final Entity entity, final int sectionIndex) { ++ final BasicEntityList list = this.entitiesBySection[sectionIndex]; ++ ++ if (list == null || !list.remove(entity)) { ++ return; ++ } ++ ++ --this.count; ++ ++ if (list.isEmpty()) { ++ this.entitiesBySection[sectionIndex] = null; ++ this.nonEmptyBitset[sectionIndex >>> 6] ^= (1L << (sectionIndex & (Long.SIZE - 1))); ++ } ++ } ++ ++ public void getEntities(final Entity except, final AxisAlignedBB box, final List into, final Predicate predicate) { ++ if (this.count == 0) { ++ return; ++ } ++ ++ final int minSection = this.manager.minSection; ++ final int maxSection = this.manager.maxSection; ++ ++ final int min = MathHelper.clamp(MathHelper.floor(box.minY - 2.0) >> 4, minSection, maxSection); ++ final int max = MathHelper.clamp(MathHelper.floor(box.maxY + 2.0) >> 4, minSection, maxSection); ++ ++ // TODO use the bitset ++ ++ final BasicEntityList[] entitiesBySection = this.entitiesBySection; ++ ++ for (int section = min; section <= max; ++section) { ++ final BasicEntityList list = entitiesBySection[section - minSection]; ++ ++ if (list == null) { ++ continue; ++ } ++ ++ final Entity[] storage = list.storage; ++ ++ for (int i = 0, len = Math.min(storage.length, list.size()); i < len; ++i) { ++ final Entity entity = storage[i]; ++ ++ if (entity == null || entity == except || !entity.getBoundingBox().intersects(box)) { ++ continue; ++ } ++ ++ if (predicate != null && !predicate.test(entity)) { ++ continue; ++ } ++ ++ into.add(entity); ++ } ++ } ++ } ++ ++ public void getEntitiesWithEnderDragonParts(final Entity except, final AxisAlignedBB box, final List into, ++ final Predicate predicate) { ++ if (this.count == 0) { ++ return; ++ } ++ ++ final int minSection = this.manager.minSection; ++ final int maxSection = this.manager.maxSection; ++ ++ final int min = MathHelper.clamp(MathHelper.floor(box.minY - 2.0) >> 4, minSection, maxSection); ++ final int max = MathHelper.clamp(MathHelper.floor(box.maxY + 2.0) >> 4, minSection, maxSection); ++ ++ // TODO use the bitset ++ ++ final BasicEntityList[] entitiesBySection = this.entitiesBySection; ++ ++ for (int section = min; section <= max; ++section) { ++ final BasicEntityList list = entitiesBySection[section - minSection]; ++ ++ if (list == null) { ++ continue; ++ } ++ ++ final Entity[] storage = list.storage; ++ ++ for (int i = 0, len = Math.min(storage.length, list.size()); i < len; ++i) { ++ final Entity entity = storage[i]; ++ ++ if (entity == null || entity == except || !entity.getBoundingBox().intersects(box)) { ++ continue; ++ } ++ ++ if (predicate != null && !predicate.test(entity)) { ++ continue; ++ } ++ ++ into.add(entity); ++ ++ if (entity instanceof EntityEnderDragon) { ++ for (final EntityComplexPart part : ((EntityEnderDragon)entity).children) { ++ if (part == except || !part.getBoundingBox().intersects(box)) { ++ continue; ++ } ++ ++ if (predicate != null && !predicate.test(part)) { ++ continue; ++ } ++ ++ into.add(part); ++ } ++ } ++ } ++ } ++ } ++ ++ public void getEntities(final EntityTypes type, final AxisAlignedBB box, final List into, ++ final Predicate predicate) { ++ if (this.count == 0) { ++ return; ++ } ++ ++ final int minSection = this.manager.minSection; ++ final int maxSection = this.manager.maxSection; ++ ++ final int min = MathHelper.clamp(MathHelper.floor(box.minY - 2.0) >> 4, minSection, maxSection); ++ final int max = MathHelper.clamp(MathHelper.floor(box.maxY + 2.0) >> 4, minSection, maxSection); ++ ++ // TODO use the bitset ++ ++ final BasicEntityList[] entitiesBySection = this.entitiesBySection; ++ ++ for (int section = min; section <= max; ++section) { ++ final BasicEntityList list = entitiesBySection[section - minSection]; ++ ++ if (list == null) { ++ continue; ++ } ++ ++ final Entity[] storage = list.storage; ++ ++ for (int i = 0, len = Math.min(storage.length, list.size()); i < len; ++i) { ++ final Entity entity = storage[i]; ++ ++ if (entity == null || (type != null && entity.getEntityType() != type) || !entity.getBoundingBox().intersects(box)) { ++ continue; ++ } ++ ++ if (predicate != null && !predicate.test((T)entity)) { ++ continue; ++ } ++ ++ into.add((T)entity); ++ } ++ } ++ } ++ } ++} +diff --git a/src/main/java/com/tuinity/tuinity/world/EntitySliceManager.java b/src/main/java/com/tuinity/tuinity/world/EntitySliceManager.java +new file mode 100644 +index 0000000000000000000000000000000000000000..000ab23a48186d6b910c62e6922af3b85c198fca +--- /dev/null ++++ b/src/main/java/com/tuinity/tuinity/world/EntitySliceManager.java +@@ -0,0 +1,115 @@ ++package com.tuinity.tuinity.world; ++ ++import com.tuinity.tuinity.util.CoordinateUtils; ++import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; ++import net.minecraft.server.WorldServer; ++import java.util.concurrent.locks.StampedLock; ++ ++public final class EntitySliceManager { ++ ++ protected static final int REGION_SHIFT = 5; ++ protected static final int REGION_MASK = (1 << REGION_SHIFT) - 1; ++ protected static final int REGION_SIZE = 1 << REGION_SHIFT; ++ ++ public final WorldServer world; ++ ++ private final StampedLock stateLock = new StampedLock(); ++ protected final Long2ObjectOpenHashMap regions = new Long2ObjectOpenHashMap<>(32, 0.7f); ++ ++ public EntitySliceManager(final WorldServer world) { ++ this.world = world; ++ } ++ ++ public ChunkSlicesRegion getRegion(final int regionX, final int regionZ) { ++ final long key = CoordinateUtils.getChunkKey(regionX, regionZ); ++ final long attempt = this.stateLock.tryOptimisticRead(); ++ if (attempt != 0L) { ++ try { ++ final ChunkSlicesRegion ret = this.regions.get(key); ++ ++ if (this.stateLock.validate(attempt)) { ++ return ret; ++ } ++ } catch (final Error error) { ++ throw error; ++ } catch (final Throwable thr) { ++ // ignore ++ } ++ } ++ ++ this.stateLock.readLock(); ++ try { ++ return this.regions.get(key); ++ } finally { ++ this.stateLock.tryUnlockRead(); ++ } ++ } ++ ++ public synchronized void removeChunk(final int chunkX, final int chunkZ) { ++ final long key = CoordinateUtils.getChunkKey(chunkX >> REGION_SHIFT, chunkZ >> REGION_SHIFT); ++ final int relIndex = (chunkX & REGION_MASK) | ((chunkZ & REGION_MASK) << REGION_SHIFT); ++ ++ final ChunkSlicesRegion region = this.regions.get(key); ++ final int remaining = region.remove(relIndex); ++ ++ if (remaining == 0) { ++ this.stateLock.writeLock(); ++ try { ++ this.regions.remove(key); ++ } finally { ++ this.stateLock.tryUnlockWrite(); ++ } ++ } ++ } ++ ++ public synchronized void addChunk(final int chunkX, final int chunkZ, final ChunkEntitySlices slices) { ++ final long key = CoordinateUtils.getChunkKey(chunkX >> REGION_SHIFT, chunkZ >> REGION_SHIFT); ++ final int relIndex = (chunkX & REGION_MASK) | ((chunkZ & REGION_MASK) << REGION_SHIFT); ++ ++ ChunkSlicesRegion region = this.regions.get(key); ++ if (region != null) { ++ region.add(relIndex, slices); ++ } else { ++ region = new ChunkSlicesRegion(); ++ region.add(relIndex, slices); ++ this.stateLock.writeLock(); ++ try { ++ this.regions.put(key, region); ++ } finally { ++ this.stateLock.tryUnlockWrite(); ++ } ++ } ++ } ++ ++ public static final class ChunkSlicesRegion { ++ ++ protected final ChunkEntitySlices[] slices = new ChunkEntitySlices[REGION_SIZE * REGION_SIZE]; ++ protected int sliceCount; ++ ++ public ChunkEntitySlices get(final int index) { ++ return this.slices[index]; ++ } ++ ++ public int remove(final int index) { ++ final ChunkEntitySlices slices = this.slices[index]; ++ if (slices == null) { ++ throw new IllegalStateException(); ++ } ++ ++ this.slices[index] = null; ++ ++ return --this.sliceCount; ++ } ++ ++ public void add(final int index, final ChunkEntitySlices slices) { ++ final ChunkEntitySlices curr = this.slices[index]; ++ if (curr != null) { ++ throw new IllegalStateException(); ++ } ++ ++ this.slices[index] = slices; ++ ++ ++this.sliceCount; ++ } ++ } ++} +diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java +index dface62144bb230c576e9eafad1016d19d211118..3f6dbba68fe7331c97c4e0fe3c8ada365970577a 100644 +--- a/src/main/java/net/minecraft/server/Chunk.java ++++ b/src/main/java/net/minecraft/server/Chunk.java +@@ -92,54 +92,24 @@ public class Chunk implements IChunkAccess { + // Paper end + + // Tuinity start - optimise hard collision handling +- final com.destroystokyo.paper.util.maplist.EntityList[] hardCollidingEntities = new com.destroystokyo.paper.util.maplist.EntityList[16]; +- +- { +- for (int i = 0, len = this.hardCollidingEntities.length; i < len; ++i) { +- this.hardCollidingEntities[i] = new com.destroystokyo.paper.util.maplist.EntityList(); +- } +- } ++ // Tuinity - optimised entity slices + + public final void getHardCollidingEntities(@Nullable Entity entity, AxisAlignedBB axisalignedbb, List into, Predicate predicate) { +- // copied from getEntities +- int min = MathHelper.floor((axisalignedbb.minY - 2.0D) / 16.0D); +- int max = MathHelper.floor((axisalignedbb.maxY + 2.0D) / 16.0D); +- +- min = MathHelper.clamp(min, 0, this.hardCollidingEntities.length - 1); +- max = MathHelper.clamp(max, 0, this.hardCollidingEntities.length - 1); +- +- for (int k = min; k <= max; ++k) { +- com.destroystokyo.paper.util.maplist.EntityList entityList = this.hardCollidingEntities[k]; +- Entity[] entities = entityList.getRawData(); +- +- for (int i = 0, len = entityList.size(); i < len; ++i) { +- Entity entity1 = entities[i]; +- if (entity1.shouldBeRemoved) continue; // Paper +- +- if (entity1 != entity && entity1.getBoundingBox().intersects(axisalignedbb)) { +- if (predicate == null || predicate.test(entity1)) { +- into.add(entity1); +- } +- +- if (!(entity1 instanceof EntityEnderDragon)) { +- continue; +- } ++ this.entitySlicesManager.getHardCollidingEntities(entity, axisalignedbb, into, predicate); // Tuinity ++ } ++ // Tuinity end - optimise hard collision handling + +- EntityComplexPart[] aentitycomplexpart = ((EntityEnderDragon)entity1).children; +- int l = aentitycomplexpart.length; ++ // Tuinity start - optimised entity slices ++ protected final com.tuinity.tuinity.world.ChunkEntitySlices entitySlicesManager; + +- for (int i1 = 0; i1 < l; ++i1) { +- EntityComplexPart entitycomplexpart = aentitycomplexpart[i1]; ++ public final boolean hasEntitiesMaybe(Class clazz) { // Tuinity start ++ return true; // Tuinity end ++ } + +- if (entitycomplexpart != entity && entitycomplexpart.getBoundingBox().intersects(axisalignedbb) && (predicate == null || predicate.test(entitycomplexpart))) { +- into.add(entitycomplexpart); +- } +- } +- } +- } +- } ++ public final void getEntitiesClass(Class clazz, Entity entity, AxisAlignedBB boundingBox, Predicate predicate, List into) { ++ this.entitySlicesManager.getEntities((Class)clazz, entity, boundingBox, (List)into, (Predicate)predicate); // Tuinity + } +- // Tuinity end - optimise hard collision handling ++ // Tuinity end - optimised entity slices + + public Chunk(World world, ChunkCoordIntPair chunkcoordintpair, BiomeStorage biomestorage, ChunkConverter chunkconverter, TickList ticklist, TickList ticklist1, long i, @Nullable ChunkSection[] achunksection, @Nullable Consumer consumer) { + this.sections = new ChunkSection[16]; +@@ -184,6 +154,7 @@ public class Chunk implements IChunkAccess { + + // CraftBukkit start + this.bukkitChunk = new org.bukkit.craftbukkit.CraftChunk(this); ++ this.entitySlicesManager = new com.tuinity.tuinity.world.ChunkEntitySlices(this.world, this.loc.x, this.loc.z, 0, 15); // TODO update for 1.17 // Tuinity + } + + public org.bukkit.Chunk bukkitChunk; +@@ -644,8 +615,9 @@ public class Chunk implements IChunkAccess { + entity.chunkX = this.loc.x; + entity.chunkY = k; + entity.chunkZ = this.loc.z; +- this.entities.add(entity); // Paper - per chunk entity list +- this.entitySlices[k].add(entity); if (entity.hardCollides()) this.hardCollidingEntities[k].add(entity); // Tuinity - optimise hard colliding entities ++ this.entities.add(entity); // Tuinity ++ this.entitySlices[k].add(entity); // Tuinity ++ this.entitySlicesManager.addEntity(entity, k); // Tuinity + // Paper start + if (entity instanceof EntityItem) { + itemCounts[k]++; +@@ -683,7 +655,8 @@ public class Chunk implements IChunkAccess { + entity.entitySlice = null; + entity.inChunk = false; + } +- if (entity.hardCollides()) this.hardCollidingEntities[i].remove(entity); if (!this.entitySlices[i].remove(entity)) { // Tuinity - optimise hard colliding entities ++ this.entitySlicesManager.removeEntity(entity, i); // Tuinity ++ if (!this.entitySlices[i].remove(entity)) { // Tuinity - optimise hard colliding entities // Tuinity - entities by class // Tuinity + return; + } + if (entity instanceof EntityItem) { +@@ -926,116 +899,18 @@ public class Chunk implements IChunkAccess { + } + + public void a(@Nullable Entity entity, AxisAlignedBB axisalignedbb, List list, @Nullable Predicate predicate) { +- org.spigotmc.AsyncCatcher.catchOp("Chunk getEntities call"); // Spigot +- int i = MathHelper.floor((axisalignedbb.minY - 2.0D) / 16.0D); +- int j = MathHelper.floor((axisalignedbb.maxY + 2.0D) / 16.0D); +- +- i = MathHelper.clamp(i, 0, this.entitySlices.length - 1); +- j = MathHelper.clamp(j, 0, this.entitySlices.length - 1); +- +- for (int k = i; k <= j; ++k) { +- List entityslice = this.entitySlices[k]; // Spigot +- List list1 = entityslice; // Spigot +- int l = list1.size(); +- +- for (int i1 = 0; i1 < l; ++i1) { +- Entity entity1 = (Entity) list1.get(i1); +- if (entity1.shouldBeRemoved) continue; // Paper +- +- if (entity1.getBoundingBox().c(axisalignedbb) && entity1 != entity) { +- if (predicate == null || predicate.test(entity1)) { +- list.add(entity1); +- } +- +- if (entity1 instanceof EntityEnderDragon) { +- EntityComplexPart[] aentitycomplexpart = ((EntityEnderDragon) entity1).eJ(); +- int j1 = aentitycomplexpart.length; +- +- for (int k1 = 0; k1 < j1; ++k1) { +- EntityComplexPart entitycomplexpart = aentitycomplexpart[k1]; +- +- if (entitycomplexpart != entity && entitycomplexpart.getBoundingBox().c(axisalignedbb) && (predicate == null || predicate.test(entitycomplexpart))) { +- list.add(entitycomplexpart); +- } +- } +- } +- } +- } +- } ++ this.entitySlicesManager.getEntities(entity, axisalignedbb, list, predicate); // Tuinity - optimised entity slices + + } + + public void a(@Nullable EntityTypes entitytypes, AxisAlignedBB axisalignedbb, List list, Predicate predicate) { +- org.spigotmc.AsyncCatcher.catchOp("Chunk getEntities call"); // Spigot +- int i = MathHelper.floor((axisalignedbb.minY - 2.0D) / 16.0D); +- int j = MathHelper.floor((axisalignedbb.maxY + 2.0D) / 16.0D); +- +- i = MathHelper.clamp(i, 0, this.entitySlices.length - 1); +- j = MathHelper.clamp(j, 0, this.entitySlices.length - 1); +- +- for (int k = i; k <= j; ++k) { +- Iterator iterator = this.entitySlices[k].iterator(); // Spigot +- +- // Paper start - Don't search for inventories if we have none, and that is all we want +- /* +- * We check if they want inventories by seeing if it is the static `IEntitySelector.d` +- * +- * Make sure the inventory selector stays in sync. +- * It should be the one that checks `var1 instanceof IInventory && var1.isAlive()` +- */ +- if (predicate == IEntitySelector.isInventory() && inventoryEntityCounts[k] <= 0) continue; +- while (iterator.hasNext()) { +- T entity = (T) iterator.next(); // CraftBukkit - decompile error +- if (entity.shouldBeRemoved) continue; // Paper +- +- if ((entitytypes == null || entity.getEntityType() == entitytypes) && entity.getBoundingBox().c(axisalignedbb) && predicate.test(entity)) { +- list.add(entity); +- } +- } +- } ++ this.entitySlicesManager.getEntities(entitytypes, axisalignedbb, (List)list, (Predicate)predicate); // Tuinity - optimised entity slices + + } + ++ public final void getEntities(Class oclass, AxisAlignedBB axisalignedbb, List list, @Nullable Predicate predicate) { this.a(oclass, axisalignedbb, list, predicate); } // Tuinity - OBFHELPER + public void a(Class oclass, AxisAlignedBB axisalignedbb, List list, @Nullable Predicate predicate) { +- org.spigotmc.AsyncCatcher.catchOp("Chunk getEntities call"); // Spigot +- int i = MathHelper.floor((axisalignedbb.minY - 2.0D) / 16.0D); +- int j = MathHelper.floor((axisalignedbb.maxY + 2.0D) / 16.0D); +- +- i = MathHelper.clamp(i, 0, this.entitySlices.length - 1); +- j = MathHelper.clamp(j, 0, this.entitySlices.length - 1); +- +- // Paper start +- int[] counts; +- if (EntityItem.class.isAssignableFrom(oclass)) { +- counts = itemCounts; +- } else if (IInventory.class.isAssignableFrom(oclass)) { +- counts = inventoryEntityCounts; +- } else { +- counts = null; +- } +- // Paper end +- for (int k = i; k <= j; ++k) { +- if (counts != null && counts[k] <= 0) continue; // Paper - Don't check a chunk if it doesn't have the type we are looking for +- Iterator iterator = this.entitySlices[k].iterator(); // Spigot +- +- // Paper start - Don't search for inventories if we have none, and that is all we want +- /* +- * We check if they want inventories by seeing if it is the static `IEntitySelector.d` +- * +- * Make sure the inventory selector stays in sync. +- * It should be the one that checks `var1 instanceof IInventory && var1.isAlive()` +- */ +- if (predicate == IEntitySelector.isInventory() && inventoryEntityCounts[k] <= 0) continue; +- // Paper end +- while (iterator.hasNext()) { +- T t0 = (T) iterator.next(); // CraftBukkit - decompile error +- if (t0.shouldBeRemoved) continue; // Paper +- +- if (oclass.isInstance(t0) && t0.getBoundingBox().c(axisalignedbb) && (predicate == null || predicate.test(t0))) { // Spigot - instance check +- list.add(t0); +- } +- } +- } ++ this.entitySlicesManager.getEntities(oclass, null, axisalignedbb, list, predicate); // Tuinity - optimised entity slices + + } + +diff --git a/src/main/java/net/minecraft/server/IEntityAccess.java b/src/main/java/net/minecraft/server/IEntityAccess.java +index c17cbadeff9cb3ea955b9db99ab71d6d7fd8c247..93f2ac996904ddefed04704e554209d047faa59f 100644 +--- a/src/main/java/net/minecraft/server/IEntityAccess.java ++++ b/src/main/java/net/minecraft/server/IEntityAccess.java +@@ -214,12 +214,12 @@ public interface IEntityAccess { + } + + @Nullable +- default T a(Class oclass, PathfinderTargetCondition pathfindertargetcondition, @Nullable EntityLiving entityliving, double d0, double d1, double d2, AxisAlignedBB axisalignedbb) { ++ default T a(Class oclass, PathfinderTargetCondition pathfindertargetcondition, @Nullable EntityLiving entityliving, double d0, double d1, double d2, AxisAlignedBB axisalignedbb) { // Tuinity - diff on change, override in World - this should be "get closest entity by class that matches path finder target condition" + return this.a(this.a(oclass, axisalignedbb, null), pathfindertargetcondition, entityliving, d0, d1, d2); // Paper - decompile fix + } + + @Nullable +- default T b(Class oclass, PathfinderTargetCondition pathfindertargetcondition, @Nullable EntityLiving entityliving, double d0, double d1, double d2, AxisAlignedBB axisalignedbb) { ++ default T b(Class oclass, PathfinderTargetCondition pathfindertargetcondition, @Nullable EntityLiving entityliving, double d0, double d1, double d2, AxisAlignedBB axisalignedbb) { // Tuinity - diff on change, override in World - this should be "get closest entity by class that matches path finder target condition" + return this.a(this.b(oclass, axisalignedbb, null), pathfindertargetcondition, entityliving, d0, d1, d2); // Paper - decompile fix + } + +diff --git a/src/main/java/net/minecraft/server/PathfinderTargetCondition.java b/src/main/java/net/minecraft/server/PathfinderTargetCondition.java +index 253377c6238594de1f76cafcbf8223592e4d3f6b..3ebe3d0dc4c2c6aee6ea349006a74cbe5aa8e78f 100644 +--- a/src/main/java/net/minecraft/server/PathfinderTargetCondition.java ++++ b/src/main/java/net/minecraft/server/PathfinderTargetCondition.java +@@ -51,6 +51,7 @@ public class PathfinderTargetCondition { + return this; + } + ++ public final boolean test(@Nullable EntityLiving entityliving, EntityLiving entityliving1) { return this.a(entityliving, entityliving1); } // Tuinity - OBFHELPER + public boolean a(@Nullable EntityLiving entityliving, EntityLiving entityliving1) { + if (entityliving == entityliving1) { + return false; +diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java +index dccdbb1c218d9fd8acb81998bd5884dc4aba7c1c..1d87e7461d28d8a639fafcfdfa5496014e9180f6 100644 +--- a/src/main/java/net/minecraft/server/World.java ++++ b/src/main/java/net/minecraft/server/World.java +@@ -1186,7 +1186,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable { + Chunk chunk = (Chunk)this.getChunkIfLoadedImmediately(i1, j1); // Paper + + if (chunk != null) { +- chunk.a(oclass, axisalignedbb, list, predicate); ++ chunk.getEntitiesClass(oclass, null, axisalignedbb, (Predicate)predicate, (List)list); // Tuinity - optimise lookup by entity class + } + } + } +@@ -1209,7 +1209,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable { + Chunk chunk = (Chunk)this.getChunkIfLoadedImmediately(i1, j1); // Paper + + if (chunk != null) { +- chunk.a(oclass, axisalignedbb, list, predicate); ++ chunk.getEntitiesClass(oclass, null, axisalignedbb, (Predicate)predicate, (List)list); // Tuinity - optimise lookup by entity class + } + } + } +@@ -1217,6 +1217,106 @@ public abstract class World implements GeneratorAccess, AutoCloseable { + return list; + } + ++ // Tuinity start ++ @Override ++ public T b(Class oclass, PathfinderTargetCondition pathfindertargetcondition, @Nullable EntityLiving entityliving, double d0, double d1, double d2, AxisAlignedBB axisalignedbb) { ++ return this.getClosestEntity(oclass, pathfindertargetcondition, entityliving, d0, d1, d2, axisalignedbb); ++ } ++ ++ @Override ++ public T a(Class oclass, PathfinderTargetCondition pathfindertargetcondition, @Nullable EntityLiving entityliving, double d0, double d1, double d2, AxisAlignedBB axisalignedbb) { ++ return this.getClosestEntity(oclass, pathfindertargetcondition, entityliving, d0, d1, d2, axisalignedbb); ++ } ++ ++ public final T getClosestEntity(Class clazz, ++ PathfinderTargetCondition condition, ++ @Nullable EntityLiving source, ++ double x, double y, double z, ++ AxisAlignedBB boundingBox) { ++ org.bukkit.craftbukkit.util.UnsafeList entities = com.tuinity.tuinity.util.CachedLists.getTempGetEntitiesList(); ++ try { ++ int lowerX = MCUtil.fastFloor((boundingBox.minX - 2.0D)) >> 4; ++ int upperX = MCUtil.fastFloor((boundingBox.maxX + 2.0D)) >> 4; ++ int lowerZ = MCUtil.fastFloor((boundingBox.minZ - 2.0D)) >> 4; ++ int upperZ = MCUtil.fastFloor((boundingBox.maxZ + 2.0D)) >> 4; ++ ++ org.bukkit.craftbukkit.util.UnsafeList chunks = com.tuinity.tuinity.util.CachedLists.getTempGetChunksList(); ++ try { ++ T closest = null; ++ double closestDistance = Double.MAX_VALUE; ++ ChunkProviderServer chunkProvider = ((WorldServer)this).getChunkProvider(); ++ ++ int centerX = (lowerX + upperX) >> 1; ++ int centerZ = (lowerZ + upperZ) >> 1; ++ // Copied from MCUtil.getSpiralOutChunks ++ Chunk temp; ++ if ((temp = chunkProvider.getChunkAtIfLoadedImmediately(centerX, centerZ)) != null && temp.hasEntitiesMaybe(clazz)) { ++ chunks.add(temp); ++ } ++ int radius = Math.max((upperX - lowerX + 1) >> 1, (upperZ - lowerZ + 1) >> 1); ++ for (int r = 1; r <= radius; r++) { ++ int ox = -r; ++ int oz = r; ++ ++ // Iterates the edge of half of the box; then negates for other half. ++ while (ox <= r && oz > -r) { ++ { ++ int cx = centerX + ox; ++ int cz = centerZ + oz; ++ if (cx >= lowerX && cx <= upperX && cz >= lowerZ && cz <= upperZ && ++ (temp = chunkProvider.getChunkAtIfLoadedImmediately(cx, cz)) != null && ++ temp.hasEntitiesMaybe(clazz)) { ++ chunks.add(temp); ++ } ++ } ++ { ++ int cx = centerX - ox; ++ int cz = centerZ - oz; ++ if (cx >= lowerX && cx <= upperX && cz >= lowerZ && cz <= upperZ && ++ (temp = chunkProvider.getChunkAtIfLoadedImmediately(cx, cz)) != null && ++ temp.hasEntitiesMaybe(clazz)) { ++ chunks.add(temp); ++ } ++ } ++ ++ if (ox < r) { ++ ox++; ++ } else { ++ oz--; ++ } ++ } ++ } ++ ++ Object[] chunkData = chunks.getRawDataArray(); ++ for (int cindex = 0, clen = chunks.size(); cindex < clen; ++cindex) { ++ final Chunk chunk = (Chunk)chunkData[cindex]; ++ ++ chunk.getEntitiesClass(clazz, source, boundingBox, null, entities); ++ ++ Object[] entityData = entities.getRawDataArray(); ++ for (int eindex = 0, entities_len = entities.size(); eindex < entities_len; ++eindex) { ++ T entity = (T)entityData[eindex]; ++ double distance = entity.getDistanceSquared(x, y, z); ++ // check distance first, as it's the least expensive ++ if (distance < closestDistance && condition.test(source, entity)) { ++ closest = entity; ++ closestDistance = distance; ++ } ++ } ++ ++ entities.setSize(0); ++ } ++ ++ return closest; ++ } finally { ++ com.tuinity.tuinity.util.CachedLists.returnTempGetChunksList(chunks); ++ } ++ } finally { ++ com.tuinity.tuinity.util.CachedLists.returnTempGetEntitiesList(entities); ++ } ++ } ++ // Tuinity end ++ + @Nullable + public abstract Entity getEntity(int i); + +diff --git a/src/main/java/org/bukkit/craftbukkit/util/UnsafeList.java b/src/main/java/org/bukkit/craftbukkit/util/UnsafeList.java +index 50f855b931dba60754fff9c7cdf5e0e744f00fdd..7c0d90552eeb6de7dab174e2ba4acfc89a7b3db0 100644 +--- a/src/main/java/org/bukkit/craftbukkit/util/UnsafeList.java ++++ b/src/main/java/org/bukkit/craftbukkit/util/UnsafeList.java +@@ -35,6 +35,13 @@ public class UnsafeList extends AbstractList implements List, RandomAcc + iterPool[0] = new Itr(); + } + ++ // Tuinity start ++ @Override ++ public void sort(java.util.Comparator c) { ++ Arrays.sort((E[])this.data, 0, size, c); ++ } ++ // Tuinity end ++ + public UnsafeList(int capacity) { + this(capacity, 5); + } diff --git a/patches/Tuinity/patches/server/0047-Optimise-EntityInsentient-checkDespawn.patch b/patches/Tuinity/patches/server/0047-Optimise-EntityInsentient-checkDespawn.patch deleted file mode 100644 index 48f2c680..00000000 --- a/patches/Tuinity/patches/server/0047-Optimise-EntityInsentient-checkDespawn.patch +++ /dev/null @@ -1,273 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Spottedleaf -Date: Thu, 27 Aug 2020 16:22:52 -0700 -Subject: [PATCH] Optimise EntityInsentient#checkDespawn - -Use a distance map to map out close players. -Note that it's important that we cache the distance map value per chunk -since the penalty of a map lookup could outweigh the benefits of -searching less players (as it basically did in the outside range patch). - -diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java -index cd4a36a2f0feb2df928ee5ed7f0bca6d996bad7f..9ea915101379913cf36b123088af3dfa9833c4ff 100644 ---- a/src/main/java/net/minecraft/server/Chunk.java -+++ b/src/main/java/net/minecraft/server/Chunk.java -@@ -157,6 +157,85 @@ public class Chunk implements IChunkAccess { - } - // Tuinity end - entity slices by class - -+ // Tuinity start - optimise checkDespawn -+ private boolean playerGeneralAreaCacheSet; -+ private com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet playerGeneralAreaCache; -+ -+ void updateGeneralAreaCache() { -+ this.updateGeneralAreaCache(((WorldServer)this.world).getChunkProvider().playerChunkMap.playerGeneralAreaMap.getObjectsInRange(this.coordinateKey)); -+ } -+ -+ void updateGeneralAreaCache(com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet value) { -+ this.playerGeneralAreaCacheSet = true; -+ this.playerGeneralAreaCache = value; -+ } -+ -+ public EntityPlayer findNearestPlayer(Entity to, Predicate predicate) { -+ if (!this.playerGeneralAreaCacheSet) { -+ this.updateGeneralAreaCache(); -+ } -+ -+ com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet nearby = this.playerGeneralAreaCache; -+ -+ if (nearby == null) { -+ return null; -+ } -+ -+ Object[] backingSet = nearby.getBackingSet(); -+ double closestDistance = Double.MAX_VALUE; -+ EntityPlayer closest = null; -+ for (int i = 0, len = backingSet.length; i < len; ++i) { -+ Object _player = backingSet[i]; -+ if (!(_player instanceof EntityPlayer)) { -+ continue; -+ } -+ EntityPlayer player = (EntityPlayer)_player; -+ -+ double distance = to.getDistanceSquared(player.locX(), player.locY(), player.locZ()); -+ if (distance < closestDistance && predicate.test(player)) { -+ closest = player; -+ closestDistance = distance; -+ } -+ } -+ -+ return closest; -+ } -+ -+ public void getNearestPlayers(Entity source, Predicate predicate, double range, List ret) { -+ if (!this.playerGeneralAreaCacheSet) { -+ this.updateGeneralAreaCache(); -+ } -+ -+ com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet nearby = this.playerGeneralAreaCache; -+ -+ if (nearby == null) { -+ return; -+ } -+ -+ double rangeSquared = range * range; -+ -+ Object[] backingSet = nearby.getBackingSet(); -+ for (int i = 0, len = backingSet.length; i < len; ++i) { -+ Object _player = backingSet[i]; -+ if (!(_player instanceof EntityPlayer)) { -+ continue; -+ } -+ EntityPlayer player = (EntityPlayer)_player; -+ -+ if (range >= 0.0) { -+ double distanceSquared = player.getDistanceSquared(source.locX(), source.locY(), source.locZ()); -+ if (distanceSquared > rangeSquared) { -+ continue; -+ } -+ } -+ -+ if (predicate == null || predicate.test(player)) { -+ ret.add(player); -+ } -+ } -+ } -+ // Tuinity end - optimise checkDespawn -+ - public Chunk(World world, ChunkCoordIntPair chunkcoordintpair, BiomeStorage biomestorage, ChunkConverter chunkconverter, TickList ticklist, TickList ticklist1, long i, @Nullable ChunkSection[] achunksection, @Nullable Consumer consumer) { - this.sections = new ChunkSection[16]; - this.e = Maps.newHashMap(); -diff --git a/src/main/java/net/minecraft/server/EntityInsentient.java b/src/main/java/net/minecraft/server/EntityInsentient.java -index a88521745f9f9b6935a61db52db915ea483af227..8a5e2806e68e5f4431fd9563fae780861e87632f 100644 ---- a/src/main/java/net/minecraft/server/EntityInsentient.java -+++ b/src/main/java/net/minecraft/server/EntityInsentient.java -@@ -711,7 +711,13 @@ public abstract class EntityInsentient extends EntityLiving { - if (this.world.getDifficulty() == EnumDifficulty.PEACEFUL && this.L()) { - this.die(); - } else if (!this.isPersistent() && !this.isSpecialPersistence()) { -- EntityHuman entityhuman = this.world.findNearbyPlayer(this, -1.0D, IEntitySelector.affectsSpawning); // Paper -+ // Tuinity start - optimise checkDespawn -+ Chunk chunk = this.getCurrentChunk(); -+ EntityHuman entityhuman = chunk == null || this.world.paperConfig.hardDespawnDistance >= (31 * 16 * 31 * 16) ? this.world.findNearbyPlayer(this, -1.0D, IEntitySelector.affectsSpawning) : chunk.findNearestPlayer(this, IEntitySelector.affectsSpawning); // Paper -+ if (entityhuman == null) { -+ entityhuman = ((WorldServer)this.world).playersAffectingSpawning.isEmpty() ? null : ((WorldServer)this.world).playersAffectingSpawning.get(0); -+ } -+ // Tuinity end - optimise checkDespawn - - if (entityhuman != null) { - double d0 = entityhuman.h((Entity) this); // CraftBukkit - decompile error -diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java -index a072208bcd92ffa9ed47757de291b82be2e71e8e..8b4ab23563a9a0c047267143dc3c6c5545d6c125 100644 ---- a/src/main/java/net/minecraft/server/PlayerChunk.java -+++ b/src/main/java/net/minecraft/server/PlayerChunk.java -@@ -56,6 +56,12 @@ public class PlayerChunk { - long key = net.minecraft.server.MCUtil.getCoordinateKey(this.location); - this.playersInMobSpawnRange = this.chunkMap.playerMobSpawnMap.getObjectsInRange(key); - this.playersInChunkTickRange = this.chunkMap.playerChunkTickRangeMap.getObjectsInRange(key); -+ // Tuinity start - optimise checkDespawn -+ Chunk chunk = this.getFullChunkIfCached(); -+ if (chunk != null) { -+ chunk.updateGeneralAreaCache(); -+ } -+ // Tuinity end - optimise checkDespawn - } - // Paper end - optimise isOutsideOfRange - // Paper start - optimize chunk status progression without jumping through thread pool -diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java -index 83f070229098ad31b8ae65ffcebe52886ef2884d..f4d5ff1d0f1ad34032aaab96e1077f4be43d4bf3 100644 ---- a/src/main/java/net/minecraft/server/PlayerChunkMap.java -+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java -@@ -195,6 +195,9 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { - public final com.destroystokyo.paper.util.misc.PlayerAreaMap playerViewDistanceTickMap; - public final com.destroystokyo.paper.util.misc.PlayerAreaMap playerViewDistanceNoTickMap; - // Paper end - no-tick view distance -+ // Tuinity start - optimise checkDespawn -+ public final com.destroystokyo.paper.util.misc.PlayerAreaMap playerGeneralAreaMap; -+ // Tuinity end - optimise checkDespawn - - void addPlayerToDistanceMaps(EntityPlayer player) { - com.tuinity.tuinity.util.TickThread.softEnsureTickThread("Cannot update distance maps off of the main thread"); // Tuinity -@@ -225,6 +228,9 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { - this.playerViewDistanceBroadcastMap.add(player, chunkX, chunkZ, effectiveNoTickViewDistance + 1); // clients need an extra neighbour to render the full view distance configured - player.needsChunkCenterUpdate = false; - // Paper end - no-tick view distance -+ // Tuinity start - optimise checkDespawn -+ this.playerGeneralAreaMap.add(player, chunkX, chunkZ, 33); -+ // Tuinity end - optimise checkDespawn - } - - void removePlayerFromDistanceMaps(EntityPlayer player) { -@@ -243,6 +249,9 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { - this.playerViewDistanceTickMap.remove(player); - this.playerViewDistanceNoTickMap.remove(player); - // Paper end - no-tick view distance -+ // Tuinity start - optimise checkDespawn -+ this.playerGeneralAreaMap.remove(player); -+ // Tuinity end - optimise checkDespawn - } - - void updateMaps(EntityPlayer player) { -@@ -274,6 +283,9 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { - this.playerViewDistanceBroadcastMap.update(player, chunkX, chunkZ, effectiveNoTickViewDistance + 1); // clients need an extra neighbour to render the full view distance configured - player.needsChunkCenterUpdate = false; - // Paper end - no-tick view distance -+ // Tuinity start - optimise checkDespawn -+ this.playerGeneralAreaMap.update(player, chunkX, chunkZ, 33); -+ // Tuinity end - optimise checkDespawn - } - // Paper end - -@@ -462,6 +474,23 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { - // Tuinity start - this.dataRegionManager = new com.tuinity.tuinity.chunk.SingleThreadChunkRegionManager<>(this.world, RegionData.class, 2, (1.0 / 3.0), "Data"); - // Tuinity end -+ // Tuinity start - optimise checkDespawn -+ this.playerGeneralAreaMap = new com.destroystokyo.paper.util.misc.PlayerAreaMap(this.pooledLinkedPlayerHashSets, -+ (EntityPlayer player, int rangeX, int rangeZ, int currPosX, int currPosZ, int prevPosX, int prevPosZ, -+ com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet newState) -> { -+ Chunk chunk = PlayerChunkMap.this.world.getChunkProvider().getChunkAtIfCachedImmediately(rangeX, rangeZ); -+ if (chunk != null) { -+ chunk.updateGeneralAreaCache(newState); -+ } -+ }, -+ (EntityPlayer player, int rangeX, int rangeZ, int currPosX, int currPosZ, int prevPosX, int prevPosZ, -+ com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet newState) -> { -+ Chunk chunk = PlayerChunkMap.this.world.getChunkProvider().getChunkAtIfCachedImmediately(rangeX, rangeZ); -+ if (chunk != null) { -+ chunk.updateGeneralAreaCache(newState); -+ } -+ }); -+ // Tuinity end - optimise checkDespawn - } - // Paper start - Chunk Prioritization - public void queueHolderUpdate(PlayerChunk playerchunk) { -diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index 1d87e7461d28d8a639fafcfdfa5496014e9180f6..93c0c3376c3cb2fe416c8ae3e740ffda5f985b78 100644 ---- a/src/main/java/net/minecraft/server/World.java -+++ b/src/main/java/net/minecraft/server/World.java -@@ -123,6 +123,34 @@ public abstract class World implements GeneratorAccess, AutoCloseable { - return typeKey; - } - -+ // Tuinity start - optimise checkDespawn -+ public final List getNearbyPlayers(Entity source, double maxRange, Predicate predicate) { -+ Chunk chunk = source.getCurrentChunk(); -+ if (chunk == null || maxRange < 0.0 || maxRange > 31.0*16.0) { -+ return this.getNearbyPlayersSlow(source, maxRange, predicate); -+ } -+ -+ List ret = new java.util.ArrayList<>(); -+ chunk.getNearestPlayers(source, predicate, maxRange, ret); -+ return ret; -+ } -+ -+ private List getNearbyPlayersSlow(Entity source, double maxRange, Predicate predicate) { -+ List ret = new java.util.ArrayList<>(); -+ double maxRangeSquared = maxRange * maxRange; -+ -+ for (EntityHuman player : this.getPlayers()) { -+ if ((maxRange < 0.0 || player.getDistanceSquared(source.locX(), source.locY(), source.locZ()) < maxRangeSquared)) { -+ if (predicate == null || predicate.test(player)) { -+ ret.add((EntityPlayer)player); -+ } -+ } -+ } -+ -+ return ret; -+ } -+ // Tuinity end - optimise checkDespawn -+ - protected World(WorldDataMutable worlddatamutable, ResourceKey resourcekey, final DimensionManager dimensionmanager, Supplier supplier, boolean flag, boolean flag1, long i, org.bukkit.generator.ChunkGenerator gen, org.bukkit.World.Environment env, java.util.concurrent.Executor executor) { // Paper - this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((WorldDataServer) worlddatamutable).getName()); // Spigot - this.paperConfig = new com.destroystokyo.paper.PaperWorldConfig(((WorldDataServer) worlddatamutable).getName(), this.spigotConfig); // Paper -diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index 6e5a3467f92c29181d26c03ecf49d598d75a4633..b1b63a11a6585971685b9ace1b6d91643a36aa95 100644 ---- a/src/main/java/net/minecraft/server/WorldServer.java -+++ b/src/main/java/net/minecraft/server/WorldServer.java -@@ -301,6 +301,10 @@ public class WorldServer extends World implements GeneratorAccessSeed { - long lastMidTickExecuteFailure; - // Tuinity end - execute chunk tasks mid tick - -+ // Tuinity start - optimise checkDespawn -+ final List playersAffectingSpawning = new java.util.ArrayList<>(); -+ // Tuinity end - optimise checkDespawn -+ - // Add env and gen to constructor, WorldData -> WorldDataServer - public WorldServer(MinecraftServer minecraftserver, Executor executor, Convertable.ConversionSession convertable_conversionsession, IWorldDataServer iworlddataserver, ResourceKey resourcekey, DimensionManager dimensionmanager, WorldLoadListener worldloadlistener, ChunkGenerator chunkgenerator, boolean flag, long i, List list, boolean flag1, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen) { - super(iworlddataserver, resourcekey, dimensionmanager, minecraftserver::getMethodProfiler, false, flag, i, gen, env, executor); // Paper pass executor -@@ -659,6 +663,14 @@ public class WorldServer extends World implements GeneratorAccessSeed { - - public void doTick(BooleanSupplier booleansupplier) { - GameProfilerFiller gameprofilerfiller = this.getMethodProfiler(); -+ // Tuinity start - optimise checkDespawn -+ this.playersAffectingSpawning.clear(); -+ for (EntityPlayer player : this.getPlayers()) { -+ if (IEntitySelector.affectsSpawning.test(player)) { -+ this.playersAffectingSpawning.add(player); -+ } -+ } -+ // Tuinity end - optimise checkDespawn - - this.ticking = true; - gameprofilerfiller.enter("world border"); diff --git a/patches/Tuinity/patches/server/0047-Optimise-nearby-player-lookups.patch b/patches/Tuinity/patches/server/0047-Optimise-nearby-player-lookups.patch new file mode 100644 index 00000000..9b75fc9b --- /dev/null +++ b/patches/Tuinity/patches/server/0047-Optimise-nearby-player-lookups.patch @@ -0,0 +1,476 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Spottedleaf +Date: Thu, 27 Aug 2020 16:22:52 -0700 +Subject: [PATCH] Optimise nearby player lookups + +Use a distance map to map out close players. +Note that it's important that we cache the distance map value per chunk +since the penalty of a map lookup could outweigh the benefits of +searching less players (as it basically did in the outside range patch). + +diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java +index 3f6dbba68fe7331c97c4e0fe3c8ada365970577a..936c392c9faa178b5645ea79b0130e0d3e3e1368 100644 +--- a/src/main/java/net/minecraft/server/Chunk.java ++++ b/src/main/java/net/minecraft/server/Chunk.java +@@ -111,6 +111,92 @@ public class Chunk implements IChunkAccess { + } + // Tuinity end - optimised entity slices + ++ // Tuinity start - optimise checkDespawn ++ private boolean playerGeneralAreaCacheSet; ++ private com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet playerGeneralAreaCache; ++ ++ public com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet getPlayerGeneralAreaCache() { ++ if (!this.playerGeneralAreaCacheSet) { ++ this.updateGeneralAreaCache(); ++ } ++ return this.playerGeneralAreaCache; ++ } ++ ++ void updateGeneralAreaCache() { ++ this.updateGeneralAreaCache(((WorldServer)this.world).getChunkProvider().playerChunkMap.playerGeneralAreaMap.getObjectsInRange(this.coordinateKey)); ++ } ++ ++ void updateGeneralAreaCache(com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet value) { ++ this.playerGeneralAreaCacheSet = true; ++ this.playerGeneralAreaCache = value; ++ } ++ ++ public EntityPlayer findNearestPlayer(double sourceX, double sourceY, double sourceZ, double maxRange, Predicate predicate) { ++ if (!this.playerGeneralAreaCacheSet) { ++ this.updateGeneralAreaCache(); ++ } ++ ++ com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet nearby = this.playerGeneralAreaCache; ++ ++ if (nearby == null) { ++ return null; ++ } ++ ++ Object[] backingSet = nearby.getBackingSet(); ++ double closestDistance = maxRange < 0.0 ? Double.MAX_VALUE : maxRange * maxRange; ++ EntityPlayer closest = null; ++ for (int i = 0, len = backingSet.length; i < len; ++i) { ++ Object _player = backingSet[i]; ++ if (!(_player instanceof EntityPlayer)) { ++ continue; ++ } ++ EntityPlayer player = (EntityPlayer)_player; ++ ++ double distance = player.getDistanceSquared(sourceX, sourceY, sourceZ); ++ if (distance < closestDistance && predicate.test(player)) { ++ closest = player; ++ closestDistance = distance; ++ } ++ } ++ ++ return closest; ++ } ++ ++ public void getNearestPlayers(double sourceX, double sourceY, double sourceZ, Predicate predicate, double range, List ret) { ++ if (!this.playerGeneralAreaCacheSet) { ++ this.updateGeneralAreaCache(); ++ } ++ ++ com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet nearby = this.playerGeneralAreaCache; ++ ++ if (nearby == null) { ++ return; ++ } ++ ++ double rangeSquared = range * range; ++ ++ Object[] backingSet = nearby.getBackingSet(); ++ for (int i = 0, len = backingSet.length; i < len; ++i) { ++ Object _player = backingSet[i]; ++ if (!(_player instanceof EntityPlayer)) { ++ continue; ++ } ++ EntityPlayer player = (EntityPlayer)_player; ++ ++ if (range >= 0.0) { ++ double distanceSquared = player.getDistanceSquared(sourceX, sourceY, sourceZ); ++ if (distanceSquared > rangeSquared) { ++ continue; ++ } ++ } ++ ++ if (predicate == null || predicate.test(player)) { ++ ret.add(player); ++ } ++ } ++ } ++ // Tuinity end - optimise checkDespawn ++ + public Chunk(World world, ChunkCoordIntPair chunkcoordintpair, BiomeStorage biomestorage, ChunkConverter chunkconverter, TickList ticklist, TickList ticklist1, long i, @Nullable ChunkSection[] achunksection, @Nullable Consumer consumer) { + this.sections = new ChunkSection[16]; + this.e = Maps.newHashMap(); +diff --git a/src/main/java/net/minecraft/server/EntityInsentient.java b/src/main/java/net/minecraft/server/EntityInsentient.java +index a88521745f9f9b6935a61db52db915ea483af227..a47217c020d2c2a3caddafa0549dc827373798dd 100644 +--- a/src/main/java/net/minecraft/server/EntityInsentient.java ++++ b/src/main/java/net/minecraft/server/EntityInsentient.java +@@ -711,7 +711,13 @@ public abstract class EntityInsentient extends EntityLiving { + if (this.world.getDifficulty() == EnumDifficulty.PEACEFUL && this.L()) { + this.die(); + } else if (!this.isPersistent() && !this.isSpecialPersistence()) { +- EntityHuman entityhuman = this.world.findNearbyPlayer(this, -1.0D, IEntitySelector.affectsSpawning); // Paper ++ // Tuinity start - optimise checkDespawn ++ Chunk chunk = this.getCurrentChunk(); ++ EntityHuman entityhuman = chunk == null || this.world.paperConfig.hardDespawnDistance >= (PlayerChunkMap.GENERAL_AREA_MAP_ACCEPTABLE_SEARCH_RANGE_SQUARED) ? this.world.findNearbyPlayer(this, -1.0D, IEntitySelector.affectsSpawning) : chunk.findNearestPlayer(this.locX(), this.locY(), this.locZ(), -1.0, IEntitySelector.affectsSpawning); // Paper ++ if (entityhuman == null) { ++ entityhuman = ((WorldServer)this.world).playersAffectingSpawning.isEmpty() ? null : ((WorldServer)this.world).playersAffectingSpawning.get(0); ++ } ++ // Tuinity end - optimise checkDespawn + + if (entityhuman != null) { + double d0 = entityhuman.h((Entity) this); // CraftBukkit - decompile error +diff --git a/src/main/java/net/minecraft/server/IEntityAccess.java b/src/main/java/net/minecraft/server/IEntityAccess.java +index 93f2ac996904ddefed04704e554209d047faa59f..ad286848ddb7803640ef7eeea46b58473dd1d0c4 100644 +--- a/src/main/java/net/minecraft/server/IEntityAccess.java ++++ b/src/main/java/net/minecraft/server/IEntityAccess.java +@@ -98,7 +98,7 @@ public interface IEntityAccess { + + default EntityHuman findNearbyPlayer(Entity entity, double d0, @Nullable Predicate predicate) { return this.findNearbyPlayer(entity.locX(), entity.locY(), entity.locZ(), d0, predicate); } // Paper + @Nullable default EntityHuman findNearbyPlayer(double d0, double d1, double d2, double d3, @Nullable Predicate predicate) { return a(d0, d1, d2, d3, predicate); } // Paper - OBFHELPER +- @Nullable default EntityHuman a(double d0, double d1, double d2, double d3, @Nullable Predicate predicate) { // Paper ++ @Nullable default EntityHuman a(double d0, double d1, double d2, double d3, @Nullable Predicate predicate) { // Paper // Tuinity - diff on change, override in World - this should be "get closest player that matches predicate" + double d4 = -1.0D; + EntityHuman entityhuman = null; + Iterator iterator = this.getPlayers().iterator(); +@@ -199,17 +199,17 @@ public interface IEntityAccess { + } + + @Nullable +- default EntityHuman a(PathfinderTargetCondition pathfindertargetcondition, EntityLiving entityliving) { ++ default EntityHuman a(PathfinderTargetCondition pathfindertargetcondition, EntityLiving entityliving) { // Tuinity - diff on change, override in World - this should be "get closest player that matches path finder target condition" + return (EntityHuman) this.a(this.getPlayers(), pathfindertargetcondition, entityliving, entityliving.locX(), entityliving.locY(), entityliving.locZ()); + } + + @Nullable +- default EntityHuman a(PathfinderTargetCondition pathfindertargetcondition, EntityLiving entityliving, double d0, double d1, double d2) { ++ default EntityHuman a(PathfinderTargetCondition pathfindertargetcondition, EntityLiving entityliving, double d0, double d1, double d2) { // Tuinity - diff on change, override in World - this should be "get closest player that matches path finder target condition" + return (EntityHuman) this.a(this.getPlayers(), pathfindertargetcondition, entityliving, d0, d1, d2); + } + + @Nullable +- default EntityHuman a(PathfinderTargetCondition pathfindertargetcondition, double d0, double d1, double d2) { ++ default EntityHuman a(PathfinderTargetCondition pathfindertargetcondition, double d0, double d1, double d2) { // Tuinity - diff on change, override in World - this should be "get closest player that matches path finder target condition" + return (EntityHuman) this.a(this.getPlayers(), pathfindertargetcondition, (EntityLiving) null, d0, d1, d2); + } + +@@ -245,7 +245,7 @@ public interface IEntityAccess { + return t0; + } + +- default List a(PathfinderTargetCondition pathfindertargetcondition, EntityLiving entityliving, AxisAlignedBB axisalignedbb) { ++ default List a(PathfinderTargetCondition pathfindertargetcondition, EntityLiving entityliving, AxisAlignedBB axisalignedbb) { // Tuinity - diff on change, override in World - this should be "get players that matches path finder target condition" + List list = Lists.newArrayList(); + Iterator iterator = this.getPlayers().iterator(); + +diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java +index 48976b1f07aeb0d588d0856f18b6fd07b2d18e05..a22021766b3bffa4f96d1d4ee546b12e96b5ca58 100644 +--- a/src/main/java/net/minecraft/server/PlayerChunk.java ++++ b/src/main/java/net/minecraft/server/PlayerChunk.java +@@ -56,6 +56,12 @@ public class PlayerChunk { + long key = net.minecraft.server.MCUtil.getCoordinateKey(this.location); + this.playersInMobSpawnRange = this.chunkMap.playerMobSpawnMap.getObjectsInRange(key); + this.playersInChunkTickRange = this.chunkMap.playerChunkTickRangeMap.getObjectsInRange(key); ++ // Tuinity start - optimise checkDespawn ++ Chunk chunk = this.getFullChunkIfCached(); ++ if (chunk != null) { ++ chunk.updateGeneralAreaCache(); ++ } ++ // Tuinity end - optimise checkDespawn + } + // Paper end - optimise isOutsideOfRange + // Paper start - optimize chunk status progression without jumping through thread pool +diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java +index 83f070229098ad31b8ae65ffcebe52886ef2884d..f9753b5ada318e39b48a7fd954afdd0e48cd091c 100644 +--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java ++++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java +@@ -195,6 +195,12 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { + public final com.destroystokyo.paper.util.misc.PlayerAreaMap playerViewDistanceTickMap; + public final com.destroystokyo.paper.util.misc.PlayerAreaMap playerViewDistanceNoTickMap; + // Paper end - no-tick view distance ++ // Tuinity start - optimise checkDespawn ++ public static final int GENERAL_AREA_MAP_SQUARE_RADIUS = 38; ++ public static final double GENERAL_AREA_MAP_ACCEPTABLE_SEARCH_RANGE = 16.0 * (GENERAL_AREA_MAP_SQUARE_RADIUS - 1); ++ public static final double GENERAL_AREA_MAP_ACCEPTABLE_SEARCH_RANGE_SQUARED = GENERAL_AREA_MAP_ACCEPTABLE_SEARCH_RANGE * GENERAL_AREA_MAP_ACCEPTABLE_SEARCH_RANGE; ++ public final com.destroystokyo.paper.util.misc.PlayerAreaMap playerGeneralAreaMap; ++ // Tuinity end - optimise checkDespawn + + void addPlayerToDistanceMaps(EntityPlayer player) { + com.tuinity.tuinity.util.TickThread.softEnsureTickThread("Cannot update distance maps off of the main thread"); // Tuinity +@@ -225,6 +231,9 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { + this.playerViewDistanceBroadcastMap.add(player, chunkX, chunkZ, effectiveNoTickViewDistance + 1); // clients need an extra neighbour to render the full view distance configured + player.needsChunkCenterUpdate = false; + // Paper end - no-tick view distance ++ // Tuinity start - optimise checkDespawn ++ this.playerGeneralAreaMap.add(player, chunkX, chunkZ, GENERAL_AREA_MAP_SQUARE_RADIUS); ++ // Tuinity end - optimise checkDespawn + } + + void removePlayerFromDistanceMaps(EntityPlayer player) { +@@ -243,6 +252,9 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { + this.playerViewDistanceTickMap.remove(player); + this.playerViewDistanceNoTickMap.remove(player); + // Paper end - no-tick view distance ++ // Tuinity start - optimise checkDespawn ++ this.playerGeneralAreaMap.remove(player); ++ // Tuinity end - optimise checkDespawn + } + + void updateMaps(EntityPlayer player) { +@@ -274,6 +286,9 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { + this.playerViewDistanceBroadcastMap.update(player, chunkX, chunkZ, effectiveNoTickViewDistance + 1); // clients need an extra neighbour to render the full view distance configured + player.needsChunkCenterUpdate = false; + // Paper end - no-tick view distance ++ // Tuinity start - optimise checkDespawn ++ this.playerGeneralAreaMap.update(player, chunkX, chunkZ, GENERAL_AREA_MAP_SQUARE_RADIUS); ++ // Tuinity end - optimise checkDespawn + } + // Paper end + +@@ -462,6 +477,23 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { + // Tuinity start + this.dataRegionManager = new com.tuinity.tuinity.chunk.SingleThreadChunkRegionManager<>(this.world, RegionData.class, 2, (1.0 / 3.0), "Data"); + // Tuinity end ++ // Tuinity start - optimise checkDespawn ++ this.playerGeneralAreaMap = new com.destroystokyo.paper.util.misc.PlayerAreaMap(this.pooledLinkedPlayerHashSets, ++ (EntityPlayer player, int rangeX, int rangeZ, int currPosX, int currPosZ, int prevPosX, int prevPosZ, ++ com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet newState) -> { ++ Chunk chunk = PlayerChunkMap.this.world.getChunkProvider().getChunkAtIfCachedImmediately(rangeX, rangeZ); ++ if (chunk != null) { ++ chunk.updateGeneralAreaCache(newState); ++ } ++ }, ++ (EntityPlayer player, int rangeX, int rangeZ, int currPosX, int currPosZ, int prevPosX, int prevPosZ, ++ com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet newState) -> { ++ Chunk chunk = PlayerChunkMap.this.world.getChunkProvider().getChunkAtIfCachedImmediately(rangeX, rangeZ); ++ if (chunk != null) { ++ chunk.updateGeneralAreaCache(newState); ++ } ++ }); ++ // Tuinity end - optimise checkDespawn + } + // Paper start - Chunk Prioritization + public void queueHolderUpdate(PlayerChunk playerchunk) { +diff --git a/src/main/java/net/minecraft/server/SpawnerCreature.java b/src/main/java/net/minecraft/server/SpawnerCreature.java +index 661ad8f8e67046211e001ea40d97660d7c88f8e5..a77b1d61b9dcb0a2a27d7e50357eaf44c99a661e 100644 +--- a/src/main/java/net/minecraft/server/SpawnerCreature.java ++++ b/src/main/java/net/minecraft/server/SpawnerCreature.java +@@ -216,7 +216,7 @@ public final class SpawnerCreature { + blockposition_mutableblockposition.d(l, i, i1); + double d0 = (double) l + 0.5D; + double d1 = (double) i1 + 0.5D; +- EntityHuman entityhuman = worldserver.a(d0, (double) i, d1, -1.0D, false); ++ EntityHuman entityhuman = worldserver.a(d0, (double) i, d1, 576.0D, false); // Tuinity - copied from below method for range, for the love of god we do not need to fucking find the closet player outside of this range - limiting range lets us use the distance map + + if (entityhuman != null) { + double d2 = entityhuman.h(d0, (double) i, d1); +@@ -288,7 +288,7 @@ public final class SpawnerCreature { + } + + private static boolean a(WorldServer worldserver, IChunkAccess ichunkaccess, BlockPosition.MutableBlockPosition blockposition_mutableblockposition, double d0) { +- if (d0 <= 576.0D) { ++ if (d0 <= 576.0D) { // Tuinity - diff on change, copy into caller + return false; + } else if (worldserver.getSpawn().a((IPosition) (new Vec3D((double) blockposition_mutableblockposition.getX() + 0.5D, (double) blockposition_mutableblockposition.getY(), (double) blockposition_mutableblockposition.getZ() + 0.5D)), 24.0D)) { + return false; +diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java +index 1d87e7461d28d8a639fafcfdfa5496014e9180f6..970c1be5477a01ab9c6d79e84c519e22775564ff 100644 +--- a/src/main/java/net/minecraft/server/World.java ++++ b/src/main/java/net/minecraft/server/World.java +@@ -123,6 +123,65 @@ public abstract class World implements GeneratorAccess, AutoCloseable { + return typeKey; + } + ++ // Tuinity start - optimise checkDespawn ++ public final List getNearbyPlayers(@Nullable Entity source, double sourceX, double sourceY, double sourceZ, double maxRange, @Nullable Predicate predicate) { ++ Chunk chunk; ++ if (source == null || (chunk = source.getCurrentChunk()) == null || maxRange < 0.0 || maxRange >= PlayerChunkMap.GENERAL_AREA_MAP_ACCEPTABLE_SEARCH_RANGE) { ++ return this.getNearbyPlayersSlow(source, sourceX, sourceY, sourceZ, maxRange, predicate); ++ } ++ ++ List ret = new java.util.ArrayList<>(); ++ chunk.getNearestPlayers(sourceX, sourceY, sourceZ, predicate, maxRange, ret); ++ return ret; ++ } ++ ++ private List getNearbyPlayersSlow(@Nullable Entity source, double sourceX, double sourceY, double sourceZ, double maxRange, @Nullable Predicate predicate) { ++ List ret = new java.util.ArrayList<>(); ++ double maxRangeSquared = maxRange * maxRange; ++ ++ for (EntityPlayer player : (List)this.getPlayers()) { ++ if ((maxRange < 0.0 || player.getDistanceSquared(sourceX, sourceY, sourceZ) < maxRangeSquared)) { ++ if (predicate == null || predicate.test(player)) { ++ ret.add(player); ++ } ++ } ++ } ++ ++ return ret; ++ } ++ ++ private EntityPlayer getNearestPlayerSlow(@Nullable Entity source, double sourceX, double sourceY, double sourceZ, double maxRange, @Nullable Predicate predicate) { ++ EntityPlayer closest = null; ++ double closestRangeSquared = maxRange < 0.0 ? Double.MAX_VALUE : maxRange * maxRange; ++ ++ for (EntityPlayer player : (List)this.getPlayers()) { ++ double distanceSquared = player.getDistanceSquared(sourceX, sourceY, sourceZ); ++ if (distanceSquared < closestRangeSquared && (predicate == null || predicate.test(player))) { ++ closest = player; ++ closestRangeSquared = distanceSquared; ++ } ++ } ++ ++ return closest; ++ } ++ ++ ++ public final EntityPlayer getNearestPlayer(@Nullable Entity source, double sourceX, double sourceY, double sourceZ, double maxRange, @Nullable Predicate predicate) { ++ Chunk chunk; ++ if (source == null || (chunk = source.getCurrentChunk()) == null || maxRange < 0.0 || maxRange >= PlayerChunkMap.GENERAL_AREA_MAP_ACCEPTABLE_SEARCH_RANGE) { ++ return this.getNearestPlayerSlow(source, sourceX, sourceY, sourceZ, maxRange, predicate); ++ } ++ ++ return chunk.findNearestPlayer(sourceX, sourceY, sourceZ, maxRange, predicate); ++ } ++ ++ @Override ++ public @Nullable EntityHuman a(double d0, double d1, double d2, double d3, @Nullable Predicate predicate) { ++ return this.getNearestPlayer(null, d0, d1, d2, d3, predicate); ++ } ++ ++ // Tuinity end - optimise checkDespawn ++ + protected World(WorldDataMutable worlddatamutable, ResourceKey resourcekey, final DimensionManager dimensionmanager, Supplier supplier, boolean flag, boolean flag1, long i, org.bukkit.generator.ChunkGenerator gen, org.bukkit.World.Environment env, java.util.concurrent.Executor executor) { // Paper + this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((WorldDataServer) worlddatamutable).getName()); // Spigot + this.paperConfig = new com.destroystokyo.paper.PaperWorldConfig(((WorldDataServer) worlddatamutable).getName(), this.spigotConfig); // Paper +diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java +index 1f7cb91cc4f8d77b2ed0ffbf3a6063fc127f3871..2eb9663a3c9cedad01cd810066d6fc06ee46290c 100644 +--- a/src/main/java/net/minecraft/server/WorldServer.java ++++ b/src/main/java/net/minecraft/server/WorldServer.java +@@ -301,6 +301,107 @@ public class WorldServer extends World implements GeneratorAccessSeed { + long lastMidTickExecuteFailure; + // Tuinity end - execute chunk tasks mid tick + ++ // Tuinity start - optimise checkDespawn ++ final List playersAffectingSpawning = new java.util.ArrayList<>(); ++ // Tuinity end - optimise checkDespawn ++ // Tuinity start - optimise get nearest players for entity AI ++ public final EntityPlayer getNearestPlayer(PathfinderTargetCondition condition, @Nullable EntityLiving source, ++ double centerX, double centerY, double centerZ) { ++ com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet nearby; ++ if (source != null) { ++ Chunk chunk = source.getCurrentChunk(); ++ if (chunk != null && (MathHelper.floor(centerX) >> 4) == chunk.locX && ++ (MathHelper.floor(centerZ) >> 4) == chunk.locZ) { ++ nearby = chunk.getPlayerGeneralAreaCache(); ++ } else { ++ nearby = this.getChunkProvider().playerChunkMap.playerGeneralAreaMap.getObjectsInRange(MathHelper.floor(centerX) >> 4, MathHelper.floor(centerZ) >> 4); ++ } ++ } else { ++ nearby = this.getChunkProvider().playerChunkMap.playerGeneralAreaMap.getObjectsInRange(MathHelper.floor(centerX) >> 4, MathHelper.floor(centerZ) >> 4); ++ } ++ ++ if (nearby == null) { ++ return null; ++ } ++ ++ Object[] backingSet = nearby.getBackingSet(); ++ ++ double closestDistanceSquared = Double.MAX_VALUE; ++ EntityPlayer closest = null; ++ ++ for (int i = 0, len = backingSet.length; i < len; ++i) { ++ Object _player = backingSet[i]; ++ if (!(_player instanceof EntityPlayer)) { ++ continue; ++ } ++ EntityPlayer player = (EntityPlayer)_player; ++ ++ double distanceSquared = player.getDistanceSquared(centerX, centerY, centerZ); ++ if (distanceSquared < closestDistanceSquared && condition.test(source, player)) { ++ closest = player; ++ closestDistanceSquared = distanceSquared; ++ } ++ } ++ ++ return closest; ++ } ++ ++ @Override ++ public EntityHuman a(PathfinderTargetCondition pathfindertargetcondition, EntityLiving entityliving) { ++ return this.getNearestPlayer(pathfindertargetcondition, entityliving, entityliving.locX(), entityliving.locY(), entityliving.locZ()); ++ } ++ ++ @Override ++ public EntityHuman a(PathfinderTargetCondition pathfindertargetcondition, @Nullable EntityLiving entityliving, double d0, double d1, double d2) { ++ return this.getNearestPlayer(pathfindertargetcondition, entityliving, d0, d1, d2); ++ } ++ ++ @Override ++ public EntityHuman a(PathfinderTargetCondition pathfindertargetcondition, double d0, double d1, double d2) { ++ return this.getNearestPlayer(pathfindertargetcondition, null, d0, d1, d2); ++ } ++ ++ @Override ++ public List a(PathfinderTargetCondition condition, EntityLiving source, AxisAlignedBB axisalignedbb) { ++ com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet nearby; ++ double centerX = (axisalignedbb.maxX + axisalignedbb.minX) * 0.5; ++ double centerZ = (axisalignedbb.maxZ + axisalignedbb.minZ) * 0.5; ++ if (source != null) { ++ Chunk chunk = source.getCurrentChunk(); ++ if (chunk != null && (MathHelper.floor(centerX) >> 4) == chunk.locX && ++ (MathHelper.floor(centerZ) >> 4) == chunk.locZ) { ++ nearby = chunk.getPlayerGeneralAreaCache(); ++ } else { ++ nearby = this.getChunkProvider().playerChunkMap.playerGeneralAreaMap.getObjectsInRange(MathHelper.floor(centerX) >> 4, MathHelper.floor(centerZ) >> 4); ++ } ++ } else { ++ nearby = this.getChunkProvider().playerChunkMap.playerGeneralAreaMap.getObjectsInRange(MathHelper.floor(centerX) >> 4, MathHelper.floor(centerZ) >> 4); ++ } ++ ++ List ret = new java.util.ArrayList<>(); ++ ++ if (nearby == null) { ++ return ret; ++ } ++ ++ Object[] backingSet = nearby.getBackingSet(); ++ ++ for (int i = 0, len = backingSet.length; i < len; ++i) { ++ Object _player = backingSet[i]; ++ if (!(_player instanceof EntityPlayer)) { ++ continue; ++ } ++ EntityPlayer player = (EntityPlayer)_player; ++ ++ if (axisalignedbb.contains(player.locX(), player.locY(), player.locZ()) && condition.test(source, player)) { ++ ret.add(player); ++ } ++ } ++ ++ return ret; ++ } ++ // Tuinity end - optimise get nearest players for entity AI ++ + // Add env and gen to constructor, WorldData -> WorldDataServer + public WorldServer(MinecraftServer minecraftserver, Executor executor, Convertable.ConversionSession convertable_conversionsession, IWorldDataServer iworlddataserver, ResourceKey resourcekey, DimensionManager dimensionmanager, WorldLoadListener worldloadlistener, ChunkGenerator chunkgenerator, boolean flag, long i, List list, boolean flag1, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen) { + super(iworlddataserver, resourcekey, dimensionmanager, minecraftserver::getMethodProfiler, false, flag, i, gen, env, executor); // Paper pass executor +@@ -659,6 +760,14 @@ public class WorldServer extends World implements GeneratorAccessSeed { + + public void doTick(BooleanSupplier booleansupplier) { + GameProfilerFiller gameprofilerfiller = this.getMethodProfiler(); ++ // Tuinity start - optimise checkDespawn ++ this.playersAffectingSpawning.clear(); ++ for (EntityPlayer player : this.getPlayers()) { ++ if (IEntitySelector.affectsSpawning.test(player)) { ++ this.playersAffectingSpawning.add(player); ++ } ++ } ++ // Tuinity end - optimise checkDespawn + + this.ticking = true; + gameprofilerfiller.enter("world border"); diff --git a/patches/Tuinity/patches/server/0048-Remove-streams-for-villager-AI.patch b/patches/Tuinity/patches/server/0048-Remove-streams-for-villager-AI.patch index bb1ccbd1..ff5490ce 100644 --- a/patches/Tuinity/patches/server/0048-Remove-streams-for-villager-AI.patch +++ b/patches/Tuinity/patches/server/0048-Remove-streams-for-villager-AI.patch @@ -613,10 +613,10 @@ index f6568a54ab85bc3a682f6fbb19dda7a783625bbe..4005df5ef3dec956a54feff539db2e63 @Override diff --git a/src/main/java/net/minecraft/server/SensorNearestPlayers.java b/src/main/java/net/minecraft/server/SensorNearestPlayers.java -index 904a6d5ac61d2ac81f1057068383e9ab432852db..c8e43a9f2a23178fdef52375b7204b90b28ac20b 100644 +index 904a6d5ac61d2ac81f1057068383e9ab432852db..fa2d366ca6695c099c29469bf69a7845350b4f07 100644 --- a/src/main/java/net/minecraft/server/SensorNearestPlayers.java +++ b/src/main/java/net/minecraft/server/SensorNearestPlayers.java -@@ -19,22 +19,30 @@ public class SensorNearestPlayers extends Sensor { +@@ -19,22 +19,31 @@ public class SensorNearestPlayers extends Sensor { @Override protected void a(WorldServer worldserver, EntityLiving entityliving) { @@ -627,7 +627,8 @@ index 904a6d5ac61d2ac81f1057068383e9ab432852db..c8e43a9f2a23178fdef52375b7204b90 - entityliving.getClass(); - List list = (List) stream.sorted(Comparator.comparingDouble(entityliving::h)).collect(Collectors.toList()); + // Tuinity start - remove streams -+ List nearby = (List)worldserver.getNearbyPlayers(entityliving, 16.0, IEntitySelector.g); ++ List nearby = (List)worldserver.getNearbyPlayers(entityliving, entityliving.locX(), entityliving.locY(), entityliving.locZ(), ++ 16.0, IEntitySelector.g); + nearby.sort((e1, e2) -> Double.compare(entityliving.getDistanceSquared(e1), entityliving.getDistanceSquared(e2))); BehaviorController behaviorcontroller = entityliving.getBehaviorController(); diff --git a/patches/Tuinity/patches/server/0053-Do-not-retain-playerchunkmap-instance-in-light-threa.patch b/patches/Tuinity/patches/server/0053-Do-not-retain-playerchunkmap-instance-in-light-threa.patch index 285a755a..a34b75c3 100644 --- a/patches/Tuinity/patches/server/0053-Do-not-retain-playerchunkmap-instance-in-light-threa.patch +++ b/patches/Tuinity/patches/server/0053-Do-not-retain-playerchunkmap-instance-in-light-threa.patch @@ -7,10 +7,10 @@ The executor returned is finalizable and of course that causes issues. diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java -index f4d5ff1d0f1ad34032aaab96e1077f4be43d4bf3..caaffea1b670ddfd20bf39cbd55da1c5cf561288 100644 +index f9753b5ada318e39b48a7fd954afdd0e48cd091c..83e036f74ee00afd012f237de0642ee5699d13f8 100644 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java -@@ -337,9 +337,10 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { +@@ -340,9 +340,10 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { this.worldLoadListener = worldloadlistener; // Paper start - use light thread diff --git a/patches/Tuinity/patches/server/0058-Prevent-light-queue-overfill-when-no-players-are-onl.patch b/patches/Tuinity/patches/server/0058-Prevent-light-queue-overfill-when-no-players-are-onl.patch index 408d87de..b69ba65f 100644 --- a/patches/Tuinity/patches/server/0058-Prevent-light-queue-overfill-when-no-players-are-onl.patch +++ b/patches/Tuinity/patches/server/0058-Prevent-light-queue-overfill-when-no-players-are-onl.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Prevent light queue overfill when no players are online block changes don't queue light updates (and they shouldn't) diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java -index 0145f33f66f68a3cf03eae2128aaaa026ddc9951..9e6381a60b804a957eda5b72582d5545faebcb3e 100644 +index ce0bb4d228a73d8353d67828529879e1c99682f9..18270d44185b0ec41b9b6e1d2135e7aae3b33261 100644 --- a/src/main/java/net/minecraft/server/ChunkProviderServer.java +++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java -@@ -1211,7 +1211,7 @@ public class ChunkProviderServer extends IChunkProvider { +@@ -1221,7 +1221,7 @@ public class ChunkProviderServer extends IChunkProvider { if (ChunkProviderServer.this.tickDistanceManager()) { return true; } else { @@ -18,3 +18,16 @@ index 0145f33f66f68a3cf03eae2128aaaa026ddc9951..9e6381a60b804a957eda5b72582d5545 return super.executeNext() || execChunkTask; // Paper } } finally { +diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java +index 2eb9663a3c9cedad01cd810066d6fc06ee46290c..2814846acb8b855050a865770dcc12e00fb780d1 100644 +--- a/src/main/java/net/minecraft/server/WorldServer.java ++++ b/src/main/java/net/minecraft/server/WorldServer.java +@@ -1164,7 +1164,7 @@ public class WorldServer extends World implements GeneratorAccessSeed { + } + gameprofilerfiller.exit(); + timings.chunkTicksBlocks.stopTiming(); // Paper +- getChunkProvider().getLightEngine().queueUpdate(); // Paper ++ //getChunkProvider().getLightEngine().queueUpdate(); // Paper // Tuinity - no longer needed here, moved into task execution + // Paper end + } + } diff --git a/patches/Tuinity/patches/server/0061-Rewrite-the-light-engine.patch b/patches/Tuinity/patches/server/0061-Rewrite-the-light-engine.patch index 5529101f..69607807 100644 --- a/patches/Tuinity/patches/server/0061-Rewrite-the-light-engine.patch +++ b/patches/Tuinity/patches/server/0061-Rewrite-the-light-engine.patch @@ -4216,11 +4216,11 @@ index 2760b377d1f68ac5f66e7274317379e2dda8288a..829d4a7508e1656dbdc912096b7eafcf protected final boolean c; private final boolean[] j; diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java -index 9ea915101379913cf36b123088af3dfa9833c4ff..68d6fb69a0c1b98b3c11b6d80783faaa58272526 100644 +index 936c392c9faa178b5645ea79b0130e0d3e3e1368..8fda4702764e80dae93ef9c0eb53abc198642ab1 100644 --- a/src/main/java/net/minecraft/server/Chunk.java +++ b/src/main/java/net/minecraft/server/Chunk.java -@@ -140,6 +140,52 @@ public class Chunk implements IChunkAccess { - } +@@ -98,6 +98,52 @@ public class Chunk implements IChunkAccess { + this.entitySlicesManager.getHardCollidingEntities(entity, axisalignedbb, into, predicate); // Tuinity } // Tuinity end - optimise hard collision handling + // Tuinity start - rewrite light engine @@ -4270,9 +4270,9 @@ index 9ea915101379913cf36b123088af3dfa9833c4ff..68d6fb69a0c1b98b3c11b6d80783faaa + } + // Tuinity end - rewrite light engine - // Tuinity start - entity slices by class - private final com.tuinity.tuinity.chunk.ChunkEntitiesByClass entitiesByClass = new com.tuinity.tuinity.chunk.ChunkEntitiesByClass(this); -@@ -443,6 +489,12 @@ public class Chunk implements IChunkAccess { + // Tuinity start - optimised entity slices + protected final com.tuinity.tuinity.world.ChunkEntitySlices entitySlicesManager; +@@ -405,6 +451,12 @@ public class Chunk implements IChunkAccess { public Chunk(World world, ProtoChunk protochunk) { this(world, protochunk.getPos(), protochunk.getBiomeIndex(), protochunk.p(), protochunk.n(), protochunk.o(), protochunk.getInhabitedTime(), protochunk.getSections(), (Consumer) null); @@ -5271,10 +5271,10 @@ index a22f0cccecc85b4e4fe4603bcfa213f15c23db69..6cc4a035c8b1312b59685b20039d5e82 this.d &= ~(1 << k); if (nibblearray != null) { diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java -index 8b4ab23563a9a0c047267143dc3c6c5545d6c125..ac82f1791ce07e9a23cf97ca34974ab25e26be46 100644 +index a22021766b3bffa4f96d1d4ee546b12e96b5ca58..3127fc9dd87e82243e167862cae83ac87b7f4fa0 100644 --- a/src/main/java/net/minecraft/server/PlayerChunk.java +++ b/src/main/java/net/minecraft/server/PlayerChunk.java -@@ -383,13 +383,14 @@ public class PlayerChunk { +@@ -387,13 +387,14 @@ public class PlayerChunk { public void a(EnumSkyBlock enumskyblock, int i) { Chunk chunk = this.getSendingChunk(); // Paper - no-tick view distance @@ -5292,10 +5292,10 @@ index 8b4ab23563a9a0c047267143dc3c6c5545d6c125..ac82f1791ce07e9a23cf97ca34974ab2 } diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java -index caaffea1b670ddfd20bf39cbd55da1c5cf561288..9be1581868627b99709bcd446de6dc89c34b42d3 100644 +index 83e036f74ee00afd012f237de0642ee5699d13f8..da27ccccdce7756b94e36cc92e60b96d325412b1 100644 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java -@@ -1316,6 +1316,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { +@@ -1319,6 +1319,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { // Tuinity end - force competion on the main thread } @@ -5474,12 +5474,12 @@ index 700660dd93b3090334bb3033d5f5fdd6ab684744..e3b72922e2dfad07f3452ec5ee2af379 VoxelShape[] avoxelshape = new VoxelShape[]{VoxelShapes.a()}; diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index b1b63a11a6585971685b9ace1b6d91643a36aa95..c448f75b22ead5a178b031d625338f92752617ec 100644 +index 2814846acb8b855050a865770dcc12e00fb780d1..fda23d89da29e6a6065fc4bb57a4809f8bdb8b46 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java -@@ -305,6 +305,13 @@ public class WorldServer extends World implements GeneratorAccessSeed { - final List playersAffectingSpawning = new java.util.ArrayList<>(); - // Tuinity end - optimise checkDespawn +@@ -402,6 +402,13 @@ public class WorldServer extends World implements GeneratorAccessSeed { + } + // Tuinity end - optimise get nearest players for entity AI + // Tuinity start - rewrite light engine + /** diff --git a/patches/Tuinity/patches/server/0062-Optimise-WorldServer-notify.patch b/patches/Tuinity/patches/server/0062-Optimise-WorldServer-notify.patch index 224705b2..a2425356 100644 --- a/patches/Tuinity/patches/server/0062-Optimise-WorldServer-notify.patch +++ b/patches/Tuinity/patches/server/0062-Optimise-WorldServer-notify.patch @@ -44,10 +44,10 @@ index 55fa3911703f96cf1f97c82b19d8e2d0d220016b..b92ca4a6de01f3f86367fb8dfe3591b0 Vec3D vec3d = new Vec3D(((double) pathpoint.a + this.a.locX()) / 2.0D, ((double) pathpoint.b + this.a.locY()) / 2.0D, ((double) pathpoint.c + this.a.locZ()) / 2.0D); diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java -index 9be1581868627b99709bcd446de6dc89c34b42d3..5fe928e4511f320aef1f3b94a092d2a7d8450706 100644 +index da27ccccdce7756b94e36cc92e60b96d325412b1..490f5ce6b688101e40d2dd2683c95da2b6d5e7d5 100644 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java -@@ -291,7 +291,15 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { +@@ -294,7 +294,15 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { // Tuinity start public static enum RegionData implements com.tuinity.tuinity.chunk.SingleThreadChunkRegionManager.RegionDataCreator { @@ -65,10 +65,10 @@ index 9be1581868627b99709bcd446de6dc89c34b42d3..5fe928e4511f320aef1f3b94a092d2a7 @Override diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index c448f75b22ead5a178b031d625338f92752617ec..9a8a1e05a60bca77adc904017ae70ef5f629df0b 100644 +index fda23d89da29e6a6065fc4bb57a4809f8bdb8b46..d2b50cdc43c737d9fdfdcd7838de24cbca2017e4 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java -@@ -873,6 +873,15 @@ public class WorldServer extends World implements GeneratorAccessSeed { +@@ -970,6 +970,15 @@ public class WorldServer extends World implements GeneratorAccessSeed { gameprofilerfiller.enter("checkDespawn"); if (!entity.dead) { entity.checkDespawn(); @@ -84,7 +84,7 @@ index c448f75b22ead5a178b031d625338f92752617ec..9a8a1e05a60bca77adc904017ae70ef5 } gameprofilerfiller.exit(); -@@ -895,7 +904,14 @@ public class WorldServer extends World implements GeneratorAccessSeed { +@@ -992,7 +1001,14 @@ public class WorldServer extends World implements GeneratorAccessSeed { this.removeEntityFromChunk(entity); this.entitiesById.remove(entity.getId()); // Tuinity this.unregisterEntity(entity); @@ -99,7 +99,7 @@ index c448f75b22ead5a178b031d625338f92752617ec..9a8a1e05a60bca77adc904017ae70ef5 gameprofilerfiller.exit(); } -@@ -1304,6 +1320,12 @@ public class WorldServer extends World implements GeneratorAccessSeed { +@@ -1401,6 +1417,12 @@ public class WorldServer extends World implements GeneratorAccessSeed { int i = MathHelper.floor(entity.locX() / 16.0D); int j = Math.min(15, Math.max(0, MathHelper.floor(entity.locY() / 16.0D))); // Paper - stay consistent with chunk add/remove behavior int k = MathHelper.floor(entity.locZ() / 16.0D); @@ -112,7 +112,7 @@ index c448f75b22ead5a178b031d625338f92752617ec..9a8a1e05a60bca77adc904017ae70ef5 if (!entity.inChunk || entity.chunkX != i || entity.chunkY != j || entity.chunkZ != k) { // Paper start - remove entity if its in a chunk more correctly. -@@ -1313,6 +1335,12 @@ public class WorldServer extends World implements GeneratorAccessSeed { +@@ -1410,6 +1432,12 @@ public class WorldServer extends World implements GeneratorAccessSeed { } // Paper end @@ -125,7 +125,7 @@ index c448f75b22ead5a178b031d625338f92752617ec..9a8a1e05a60bca77adc904017ae70ef5 if (entity.inChunk && this.isChunkLoaded(entity.chunkX, entity.chunkZ)) { this.getChunkAt(entity.chunkX, entity.chunkZ).a(entity, entity.chunkY); } -@@ -1326,6 +1354,11 @@ public class WorldServer extends World implements GeneratorAccessSeed { +@@ -1423,6 +1451,11 @@ public class WorldServer extends World implements GeneratorAccessSeed { } else { this.getChunkAt(i, k).a(entity); } @@ -137,7 +137,7 @@ index c448f75b22ead5a178b031d625338f92752617ec..9a8a1e05a60bca77adc904017ae70ef5 } this.getMethodProfiler().exit(); -@@ -1788,9 +1821,96 @@ public class WorldServer extends World implements GeneratorAccessSeed { +@@ -1885,9 +1918,96 @@ public class WorldServer extends World implements GeneratorAccessSeed { // Tuinity end } new com.destroystokyo.paper.event.entity.EntityRemoveFromWorldEvent(entity.getBukkitEntity()).callEvent(); // Paper - fire while valid @@ -234,7 +234,7 @@ index c448f75b22ead5a178b031d625338f92752617ec..9a8a1e05a60bca77adc904017ae70ef5 private void registerEntity(Entity entity) { org.spigotmc.AsyncCatcher.catchOp("entity register"); // Spigot // Paper start - don't double enqueue entity registration -@@ -1971,9 +2091,25 @@ public class WorldServer extends World implements GeneratorAccessSeed { +@@ -2068,9 +2188,25 @@ public class WorldServer extends World implements GeneratorAccessSeed { VoxelShape voxelshape1 = iblockdata1.getCollisionShape(this, blockposition); if (VoxelShapes.c(voxelshape, voxelshape1, OperatorBoolean.NOT_SAME)) { @@ -261,7 +261,7 @@ index c448f75b22ead5a178b031d625338f92752617ec..9a8a1e05a60bca77adc904017ae70ef5 try { // Tuinity end while (iterator.hasNext()) { -@@ -1982,10 +2118,21 @@ public class WorldServer extends World implements GeneratorAccessSeed { +@@ -2090,10 +2226,21 @@ public class WorldServer extends World implements GeneratorAccessSeed { if (!navigationabstract.i()) { navigationabstract.b(blockposition); } diff --git a/patches/Tuinity/patches/server/0063-Actually-unload-POI-data.patch b/patches/Tuinity/patches/server/0063-Actually-unload-POI-data.patch index fb64983c..ebb66d55 100644 --- a/patches/Tuinity/patches/server/0063-Actually-unload-POI-data.patch +++ b/patches/Tuinity/patches/server/0063-Actually-unload-POI-data.patch @@ -25,10 +25,10 @@ index 13d067f48647dea63ef1bf3a2a3e0868074ba75f..04afd7f285db2f281a038e0be6f557b8 this.a(Long.MAX_VALUE, i, j, flag); } diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java -index 5fe928e4511f320aef1f3b94a092d2a7d8450706..a42571cfd2c9c80df27e59db832cb64c2a64e141 100644 +index 490f5ce6b688101e40d2dd2683c95da2b6d5e7d5..e6d39c98d0422a4f841cc836e2ac6a357b4db83a 100644 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java -@@ -838,6 +838,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { +@@ -841,6 +841,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { playerchunk = new PlayerChunk(new ChunkCoordIntPair(i), j, this.lightEngine, this.p, this); this.dataRegionManager.addChunk(playerchunk.location.x, playerchunk.location.z); // Tuinity } @@ -36,7 +36,7 @@ index 5fe928e4511f320aef1f3b94a092d2a7d8450706..a42571cfd2c9c80df27e59db832cb64c this.updatingChunks.put(i, playerchunk); this.updatingChunksModified = true; -@@ -963,7 +964,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { +@@ -966,7 +967,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { } @@ -45,7 +45,7 @@ index 5fe928e4511f320aef1f3b94a092d2a7d8450706..a42571cfd2c9c80df27e59db832cb64c protected void unloadChunks(BooleanSupplier booleansupplier) { GameProfilerFiller gameprofilerfiller = this.world.getMethodProfiler(); -@@ -1114,6 +1115,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { +@@ -1117,6 +1118,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { this.worldLoadListener.a(ichunkaccess.getPos(), (ChunkStatus) null); } if (removed) this.dataRegionManager.removeChunk(playerchunk.location.x, playerchunk.location.z); // Tuinity @@ -53,7 +53,7 @@ index 5fe928e4511f320aef1f3b94a092d2a7d8450706..a42571cfd2c9c80df27e59db832cb64c } finally { this.unloadingPlayerChunk = unloadingBefore; } // Tuinity - do not allow ticket level changes while unloading chunks } -@@ -1206,6 +1208,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { +@@ -1209,6 +1211,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { this.getVillagePlace().loadInData(chunkcoordintpair, chunkHolder.poiData); chunkHolder.tasks.forEach(Runnable::run); diff --git a/patches/Tuinity/patches/server/0065-Fix-chunks-refusing-to-unload-at-low-TPS.patch b/patches/Tuinity/patches/server/0065-Fix-chunks-refusing-to-unload-at-low-TPS.patch index 590fa53e..b20477b7 100644 --- a/patches/Tuinity/patches/server/0065-Fix-chunks-refusing-to-unload-at-low-TPS.patch +++ b/patches/Tuinity/patches/server/0065-Fix-chunks-refusing-to-unload-at-low-TPS.patch @@ -10,10 +10,10 @@ chunk future to complete. We can simply schedule to the immediate executor to get this effect, rather than the main mailbox. diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java -index a42571cfd2c9c80df27e59db832cb64c2a64e141..2c2becef8b56d7e5e998976222df85d2c8516c43 100644 +index e6d39c98d0422a4f841cc836e2ac6a357b4db83a..61570ab947b5a153a4c2bcb5a09344f060e6052d 100644 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java -@@ -1494,9 +1494,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { +@@ -1497,9 +1497,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { chunk.B(); return chunk; }); diff --git a/patches/server/0019-Optimize-TileEntity-load-unload.patch b/patches/server/0019-Optimize-TileEntity-load-unload.patch index c2a4eab8..cb6dc004 100644 --- a/patches/server/0019-Optimize-TileEntity-load-unload.patch +++ b/patches/server/0019-Optimize-TileEntity-load-unload.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Optimize TileEntity load/unload diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index 77c748ad07ee257742c4d36825bdd9e916b5d851..8285cd4b659d11d90df633cb99ab8fd36d293cc1 100644 +index 4ffaf36b40b32be25bd1944d8b8ddbc342256947..64195edf7c277d581be4d726675b09bd4a263793 100644 --- a/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java @@ -42,8 +42,8 @@ public abstract class World implements GeneratorAccess, AutoCloseable { diff --git a/patches/server/0024-Optimize-some-stuff-in-WorldServer-ticking.patch b/patches/server/0024-Optimize-some-stuff-in-WorldServer-ticking.patch index 8b090929..55f191d0 100644 --- a/patches/server/0024-Optimize-some-stuff-in-WorldServer-ticking.patch +++ b/patches/server/0024-Optimize-some-stuff-in-WorldServer-ticking.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Optimize some stuff in WorldServer ticking Replaced some streams and some array lists with glue lists diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index 2289c92c8933bfa0f382167fa5790a4ea17b7c75..1196b482d33e655eb4aa5ea6b66326f12c4363a4 100644 +index d4672e7fa899a39bae2d9179472b22db28a58f19..cca6b3585485162e8158e43dee4f8b45d4e30bea 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java -@@ -788,12 +788,21 @@ public class WorldServer extends World implements GeneratorAccessSeed { +@@ -885,12 +885,21 @@ public class WorldServer extends World implements GeneratorAccessSeed { this.server.getPlayerList().sendAll(new PacketPlayOutGameStateChange(PacketPlayOutGameStateChange.i, this.thunderLevel)); } // */ @@ -34,7 +34,7 @@ index 2289c92c8933bfa0f382167fa5790a4ea17b7c75..1196b482d33e655eb4aa5ea6b66326f1 if (flag != this.isRaining()) { // Only send weather packets to those affected for (int idx = 0; idx < this.players.size(); ++idx) { -@@ -808,11 +817,9 @@ public class WorldServer extends World implements GeneratorAccessSeed { +@@ -905,11 +914,9 @@ public class WorldServer extends World implements GeneratorAccessSeed { } } // CraftBukkit end @@ -48,7 +48,7 @@ index 2289c92c8933bfa0f382167fa5790a4ea17b7c75..1196b482d33e655eb4aa5ea6b66326f1 long l = this.worldData.getDayTime() + 24000L; TimeSkipEvent event = new TimeSkipEvent(this.getWorld(), TimeSkipEvent.SkipReason.NIGHT_SKIP, (l - l % 24000L) - this.getDayTime()); if (this.getGameRules().getBoolean(GameRules.DO_DAYLIGHT_CYCLE)) { -@@ -1038,9 +1045,9 @@ public class WorldServer extends World implements GeneratorAccessSeed { +@@ -1135,9 +1142,9 @@ public class WorldServer extends World implements GeneratorAccessSeed { } private void wakeupPlayers() { @@ -60,7 +60,7 @@ index 2289c92c8933bfa0f382167fa5790a4ea17b7c75..1196b482d33e655eb4aa5ea6b66326f1 } // Paper start - optimise random block ticking -@@ -1840,8 +1847,9 @@ public class WorldServer extends World implements GeneratorAccessSeed { +@@ -1930,8 +1937,9 @@ public class WorldServer extends World implements GeneratorAccessSeed { // Spigot start if ( entity instanceof EntityHuman ) { @@ -71,7 +71,7 @@ index 2289c92c8933bfa0f382167fa5790a4ea17b7c75..1196b482d33e655eb4aa5ea6b66326f1 for (Object o : worldData.data.values() ) { if ( o instanceof WorldMap ) -@@ -1858,7 +1866,7 @@ public class WorldServer extends World implements GeneratorAccessSeed { +@@ -1948,7 +1956,7 @@ public class WorldServer extends World implements GeneratorAccessSeed { } } } diff --git a/patches/server/0032-Fix-LightEngineThreaded-memory-leak.patch b/patches/server/0032-Fix-LightEngineThreaded-memory-leak.patch index 75092a23..92d98410 100644 --- a/patches/server/0032-Fix-LightEngineThreaded-memory-leak.patch +++ b/patches/server/0032-Fix-LightEngineThreaded-memory-leak.patch @@ -18,10 +18,10 @@ index 001ac05cf26237eec8a77c476e678ff6d0840311..7b4935dd8c54f5fcb4f26b96c270d3e4 return this.size == 0 && this.pendingTasks.isEmpty(); } diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index 1196b482d33e655eb4aa5ea6b66326f12c4363a4..be5bf0d2ebf4723a5a892f9f51aa18ea74f82fd1 100644 +index cca6b3585485162e8158e43dee4f8b45d4e30bea..68fbbcac7b6b2f24a42c3a63825f940e52f6f51a 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java -@@ -1826,6 +1826,7 @@ public class WorldServer extends World implements GeneratorAccessSeed { +@@ -1916,6 +1916,7 @@ public class WorldServer extends World implements GeneratorAccessSeed { } // Paper end diff --git a/patches/server/0059-Port-hydrogen.patch b/patches/server/0059-Port-hydrogen.patch index dc19e3cf..2b13efcd 100644 --- a/patches/server/0059-Port-hydrogen.patch +++ b/patches/server/0059-Port-hydrogen.patch @@ -336,10 +336,10 @@ index 0000000000000000000000000000000000000000..a5314a0396f4a8f373d855e873820ddd + } +} diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java -index fa1d559a07199bf52d8ae04b2c34261efdebdcdb..a3c86e6b56f744b340bc486b9d728114f884d28f 100644 +index 0924f6b484468f3cf3c2d405101c0158c12d69e6..bcf94f13414b1e8cb7438af81448e74f42a24768 100644 --- a/src/main/java/net/minecraft/server/Chunk.java +++ b/src/main/java/net/minecraft/server/Chunk.java -@@ -337,6 +337,14 @@ public class Chunk implements IChunkAccess { +@@ -298,6 +298,14 @@ public class Chunk implements IChunkAccess { // CraftBukkit start this.bukkitChunk = new org.bukkit.craftbukkit.CraftChunk(this); @@ -351,9 +351,9 @@ index fa1d559a07199bf52d8ae04b2c34261efdebdcdb..a3c86e6b56f744b340bc486b9d728114 + this.sections[i2] = null; + } + } // Yatopia end + this.entitySlicesManager = new com.tuinity.tuinity.world.ChunkEntitySlices(this.world, this.loc.x, this.loc.z, 0, 15); // TODO update for 1.17 // Tuinity this.lightningTick = this.world.random.nextInt(100000) << 1; // Airplane - initialize lightning tick } - diff --git a/src/main/java/net/minecraft/server/ChunkRegionLoader.java b/src/main/java/net/minecraft/server/ChunkRegionLoader.java index e77da341b765725771726283d3a8249b514b40da..c44333ec5b0c1914f7cb9f4b3b39626069136c22 100644 --- a/src/main/java/net/minecraft/server/ChunkRegionLoader.java diff --git a/patches/server/0063-Suspected-plugins-report.patch b/patches/server/0063-Suspected-plugins-report.patch index 435e240c..2f3ec3f8 100644 --- a/patches/server/0063-Suspected-plugins-report.patch +++ b/patches/server/0063-Suspected-plugins-report.patch @@ -108,10 +108,10 @@ index 0668d383db1f3a81d1053954d72678c7ac5aecec..7b9f83e63d0f9cd83a246be33af4ab91 ChatComponentText chatcomponenttext = new ChatComponentText("Internal server error"); diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index 8285cd4b659d11d90df633cb99ab8fd36d293cc1..aaa9a222f755622f604e5980eb2f1c0039411fa4 100644 +index 64195edf7c277d581be4d726675b09bd4a263793..bdc85c5026b9d5fe50e709cf6d5c8eb8d5f3653b 100644 --- a/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java -@@ -988,6 +988,10 @@ public abstract class World implements GeneratorAccess, AutoCloseable { +@@ -1019,6 +1019,10 @@ public abstract class World implements GeneratorAccess, AutoCloseable { // Paper start - Prevent tile entity and entity crashes String msg = "TileEntity threw exception at " + tileentity.world.getWorld().getName() + ":" + tileentity.position.getX() + "," + tileentity.position.getY() + "," + tileentity.position.getZ(); System.err.println(msg); diff --git a/upstream/Airplane b/upstream/Airplane index 8703980b..7dc1546a 160000 --- a/upstream/Airplane +++ b/upstream/Airplane @@ -1 +1 @@ -Subproject commit 8703980b48dc20f7266c77bcbdf51f376eed6204 +Subproject commit 7dc1546a25056ffef08ec6f0c7a5fb175be8d7a9 diff --git a/upstream/Empirecraft b/upstream/Empirecraft index e8696c6d..586aef63 160000 --- a/upstream/Empirecraft +++ b/upstream/Empirecraft @@ -1 +1 @@ -Subproject commit e8696c6d78fb6773480072803cab59145daa8669 +Subproject commit 586aef6305493a61736f1cd2d3858c3a67113967 diff --git a/upstream/Purpur b/upstream/Purpur index 9537c770..40868883 160000 --- a/upstream/Purpur +++ b/upstream/Purpur @@ -1 +1 @@ -Subproject commit 9537c770b0820b8b7a9915a7d571de528dc5ce8c +Subproject commit 40868883d9942e998923ee576cfa118c90e9e068 diff --git a/upstream/Tuinity b/upstream/Tuinity index 2dfd22e4..a539774b 160000 --- a/upstream/Tuinity +++ b/upstream/Tuinity @@ -1 +1 @@ -Subproject commit 2dfd22e41c4d1822f6e813317e64ff7afdb33e80 +Subproject commit a539774b11798c5640509ee33fd84c52b936b24f diff --git a/upstreamCommits/Airplane b/upstreamCommits/Airplane index ba5cd5b4..71a17603 100644 --- a/upstreamCommits/Airplane +++ b/upstreamCommits/Airplane @@ -1 +1 @@ -8703980b48dc20f7266c77bcbdf51f376eed6204 \ No newline at end of file +7dc1546a25056ffef08ec6f0c7a5fb175be8d7a9 \ No newline at end of file diff --git a/upstreamCommits/Empirecraft b/upstreamCommits/Empirecraft index f9d80edd..0c1221ca 100644 --- a/upstreamCommits/Empirecraft +++ b/upstreamCommits/Empirecraft @@ -1 +1 @@ -e8696c6d78fb6773480072803cab59145daa8669 \ No newline at end of file +586aef6305493a61736f1cd2d3858c3a67113967 \ No newline at end of file diff --git a/upstreamCommits/Purpur b/upstreamCommits/Purpur index 3fd50d31..1ed373e3 100644 --- a/upstreamCommits/Purpur +++ b/upstreamCommits/Purpur @@ -1 +1 @@ -9537c770b0820b8b7a9915a7d571de528dc5ce8c \ No newline at end of file +40868883d9942e998923ee576cfa118c90e9e068 \ No newline at end of file diff --git a/upstreamCommits/Tuinity b/upstreamCommits/Tuinity index 7d0b0088..bf7ea671 100644 --- a/upstreamCommits/Tuinity +++ b/upstreamCommits/Tuinity @@ -1 +1 @@ -2dfd22e41c4d1822f6e813317e64ff7afdb33e80 \ No newline at end of file +a539774b11798c5640509ee33fd84c52b936b24f \ No newline at end of file diff --git a/upstreamConfig/0003-Airplane.properties b/upstreamConfig/0003-Airplane.properties index e81c2083..735b7b6e 100644 --- a/upstreamConfig/0003-Airplane.properties +++ b/upstreamConfig/0003-Airplane.properties @@ -1,4 +1,4 @@ name=Airplane -useBlackList=False -list=server/Airplane-MC-Dev-Fixes.patch,server/Airplane-Configuration.patch,server/Remove-streams.patch,server/Strip-raytracing-for-EntityLiving-hasLineOfSight.patch,server/Simpler-ShapelessRecipes-comparison-for-Vanilla.patch,server/Queue-lighting-update-only-once.patch,server/Use-unmodifiableMap-instead-of-making-copy.patch,server/Swap-priority-of-checks-in-chunk-ticking.patch,server/Reduce-projectile-chunk-loading.patch,server/Optimize-random-calls-in-chunk-ticking.patch,server/Don-t-get-entity-equipment-if-not-needed.patch,server/Dynamic-activation-range.patch,server/Reduce-allocs-improve-perf-of-StructureManager.patch,server/Cache-palette-array.patch,server/Reduce-chunk-loading-lookups.patch,server/Reduce-memory-allocations.patch +useBlackList=True +list=server/Airplane-Branding-Changes.patch,server/Disable-Paper-timings-by-default.patch,server/Only-check-for-spooky-season-once-an-hour.patch branch=origin/master diff --git a/upstreamConfig/0005-Empirecraft.properties b/upstreamConfig/0005-Empirecraft.properties index 44572f58..7d2b0951 100644 --- a/upstreamConfig/0005-Empirecraft.properties +++ b/upstreamConfig/0005-Empirecraft.properties @@ -1,4 +1,4 @@ name=Empirecraft useBlackList=false -list=API/Add-ChatColor.getById.patch,server/Don-t-trigger-Lootable-Refresh-for-non-player-intera.patch,server/Fix-Bukkit.createInventory-with-type-LECTERN.patch,server/dont-load-chunks-for-physics.patch +list=API/Add-ChatColor.getById.patch,server/Don-t-trigger-Lootable-Refresh-for-non-player-intera.patch,server/Fix-Bukkit.createInventory-with-type-LECTERN.patch,server/dont-load-chunks-for-physics.patch,server/Prevent-grindstones-from-overstacking-items.patch branch=origin/master