aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--patches/server/0006-ConcurrentUtil.patch6864
-rw-r--r--patches/server/0007-CB-fixes.patch (renamed from patches/server/0006-CB-fixes.patch)4
-rw-r--r--patches/server/0008-MC-Utils.patch (renamed from patches/server/0007-MC-Utils.patch)851
-rw-r--r--patches/server/0009-Adventure.patch (renamed from patches/server/0008-Adventure.patch)12
-rw-r--r--patches/server/0010-Paper-command.patch (renamed from patches/server/0009-Paper-command.patch)2
-rw-r--r--patches/server/0012-Timings-v2.patch40
-rw-r--r--patches/server/0013-Not-implemeneted.patch (renamed from patches/server/0010-Not-implemeneted.patch)13
-rw-r--r--patches/server/0014-ChunkMapDistance-CME.patch (renamed from patches/server/0320-ChunkMapDistance-CME.patch)6
-rw-r--r--patches/server/0015-Do-not-copy-visible-chunks.patch122
-rw-r--r--patches/server/0016-Chunk-debug-command.patch (renamed from patches/server/0321-Chunk-debug-command.patch)59
-rw-r--r--patches/server/0017-Make-CallbackExecutor-strict-again.patch (renamed from patches/server/0718-Make-CallbackExecutor-strict-again.patch)4
-rw-r--r--patches/server/0018-Delay-Chunk-Unloads-based-on-Player-Movement.patch (renamed from patches/server/0426-Delay-Chunk-Unloads-based-on-Player-Movement.patch)8
-rw-r--r--patches/server/0019-Asynchronous-chunk-IO-and-loading.patch (renamed from patches/server/0252-Asynchronous-chunk-IO-and-loading.patch)198
-rw-r--r--patches/server/0020-Implement-Chunk-Priority-Urgency-System-for-Chunks.patch (renamed from patches/server/0461-Implement-Chunk-Priority-Urgency-System-for-Chunks.patch)254
-rw-r--r--patches/server/0021-Add-command-line-option-to-load-extra-plugin-jars-no.patch (renamed from patches/server/0013-Add-command-line-option-to-load-extra-plugin-jars-no.patch)2
-rw-r--r--patches/server/0022-Configurable-cactus-bamboo-and-reed-growth-heights.patch (renamed from patches/server/0014-Configurable-cactus-bamboo-and-reed-growth-heights.patch)0
-rw-r--r--patches/server/0023-Configurable-baby-zombie-movement-speed.patch (renamed from patches/server/0015-Configurable-baby-zombie-movement-speed.patch)0
-rw-r--r--patches/server/0024-Configurable-fishing-time-ranges.patch (renamed from patches/server/0016-Configurable-fishing-time-ranges.patch)0
-rw-r--r--patches/server/0025-Allow-nerfed-mobs-to-jump-and-take-water-damage.patch (renamed from patches/server/0017-Allow-nerfed-mobs-to-jump-and-take-water-damage.patch)0
-rw-r--r--patches/server/0026-Add-configurable-despawn-distances-for-living-entiti.patch (renamed from patches/server/0018-Add-configurable-despawn-distances-for-living-entiti.patch)0
-rw-r--r--patches/server/0027-Allow-for-toggling-of-spawn-chunks.patch (renamed from patches/server/0019-Allow-for-toggling-of-spawn-chunks.patch)0
-rw-r--r--patches/server/0028-Drop-falling-block-and-tnt-entities-at-the-specified.patch (renamed from patches/server/0020-Drop-falling-block-and-tnt-entities-at-the-specified.patch)0
-rw-r--r--patches/server/0029-Show-Paper-in-client-crashes-server-lists-and-Mojang.patch (renamed from patches/server/0021-Show-Paper-in-client-crashes-server-lists-and-Mojang.patch)6
-rw-r--r--patches/server/0030-Implement-Paper-VersionChecker.patch (renamed from patches/server/0022-Implement-Paper-VersionChecker.patch)2
-rw-r--r--patches/server/0031-Add-version-history-to-version-command.patch (renamed from patches/server/0023-Add-version-history-to-version-command.patch)0
-rw-r--r--patches/server/0032-Player-affects-spawning-API.patch (renamed from patches/server/0024-Player-affects-spawning-API.patch)2
-rw-r--r--patches/server/0033-Further-improve-server-tick-loop.patch (renamed from patches/server/0025-Further-improve-server-tick-loop.patch)4
-rw-r--r--patches/server/0034-Only-refresh-abilities-if-needed.patch (renamed from patches/server/0026-Only-refresh-abilities-if-needed.patch)2
-rw-r--r--patches/server/0035-Entity-Origin-API.patch (renamed from patches/server/0027-Entity-Origin-API.patch)17
-rw-r--r--patches/server/0036-Prevent-tile-entity-and-entity-crashes.patch (renamed from patches/server/0028-Prevent-tile-entity-and-entity-crashes.patch)4
-rw-r--r--patches/server/0037-Configurable-top-of-nether-void-damage.patch (renamed from patches/server/0029-Configurable-top-of-nether-void-damage.patch)2
-rw-r--r--patches/server/0038-Check-online-mode-before-converting-and-renaming-pla.patch (renamed from patches/server/0030-Check-online-mode-before-converting-and-renaming-pla.patch)0
-rw-r--r--patches/server/0039-Always-tick-falling-blocks.patch (renamed from patches/server/0031-Always-tick-falling-blocks.patch)0
-rw-r--r--patches/server/0040-Configurable-end-credits.patch (renamed from patches/server/0032-Configurable-end-credits.patch)4
-rw-r--r--patches/server/0041-Fix-lag-from-explosions-processing-dead-entities.patch (renamed from patches/server/0033-Fix-lag-from-explosions-processing-dead-entities.patch)0
-rw-r--r--patches/server/0042-Optimize-explosions.patch (renamed from patches/server/0034-Optimize-explosions.patch)2
-rw-r--r--patches/server/0043-Disable-explosion-knockback.patch (renamed from patches/server/0035-Disable-explosion-knockback.patch)2
-rw-r--r--patches/server/0044-Disable-thunder.patch (renamed from patches/server/0036-Disable-thunder.patch)4
-rw-r--r--patches/server/0045-Disable-ice-and-snow.patch (renamed from patches/server/0037-Disable-ice-and-snow.patch)4
-rw-r--r--patches/server/0046-Configurable-mob-spawner-tick-rate.patch (renamed from patches/server/0038-Configurable-mob-spawner-tick-rate.patch)0
-rw-r--r--patches/server/0047-Implement-PlayerLocaleChangeEvent.patch (renamed from patches/server/0039-Implement-PlayerLocaleChangeEvent.patch)8
-rw-r--r--patches/server/0048-Per-Player-View-Distance-API-placeholders.patch (renamed from patches/server/0040-Per-Player-View-Distance-API-placeholders.patch)8
-rw-r--r--patches/server/0049-Add-BeaconEffectEvent.patch (renamed from patches/server/0041-Add-BeaconEffectEvent.patch)0
-rw-r--r--patches/server/0050-Configurable-container-update-tick-rate.patch (renamed from patches/server/0042-Configurable-container-update-tick-rate.patch)6
-rw-r--r--patches/server/0051-Use-UserCache-for-player-heads.patch (renamed from patches/server/0043-Use-UserCache-for-player-heads.patch)0
-rw-r--r--patches/server/0052-Disable-spigot-tick-limiters.patch (renamed from patches/server/0044-Disable-spigot-tick-limiters.patch)0
-rw-r--r--patches/server/0053-Add-PlayerInitialSpawnEvent.patch (renamed from patches/server/0045-Add-PlayerInitialSpawnEvent.patch)6
-rw-r--r--patches/server/0054-Configurable-Disabling-Cat-Chest-Detection.patch (renamed from patches/server/0046-Configurable-Disabling-Cat-Chest-Detection.patch)0
-rw-r--r--patches/server/0055-Ensure-commands-are-not-ran-async.patch (renamed from patches/server/0047-Ensure-commands-are-not-ran-async.patch)8
-rw-r--r--patches/server/0056-All-chunks-are-slime-spawn-chunks-toggle.patch (renamed from patches/server/0048-All-chunks-are-slime-spawn-chunks-toggle.patch)0
-rw-r--r--patches/server/0057-Expose-server-CommandMap.patch (renamed from patches/server/0049-Expose-server-CommandMap.patch)2
-rw-r--r--patches/server/0058-Be-a-bit-more-informative-in-maxHealth-exception.patch (renamed from patches/server/0050-Be-a-bit-more-informative-in-maxHealth-exception.patch)0
-rw-r--r--patches/server/0059-Ensure-inv-drag-is-in-bounds.patch (renamed from patches/server/0051-Ensure-inv-drag-is-in-bounds.patch)0
-rw-r--r--patches/server/0060-Player-Tab-List-and-Title-APIs.patch (renamed from patches/server/0052-Player-Tab-List-and-Title-APIs.patch)2
-rw-r--r--patches/server/0061-Add-configurable-portal-search-radius.patch (renamed from patches/server/0053-Add-configurable-portal-search-radius.patch)2
-rw-r--r--patches/server/0062-Add-velocity-warnings.patch (renamed from patches/server/0054-Add-velocity-warnings.patch)8
-rw-r--r--patches/server/0063-Configurable-inter-world-teleportation-safety.patch (renamed from patches/server/0055-Configurable-inter-world-teleportation-safety.patch)2
-rw-r--r--patches/server/0064-Add-exception-reporting-event.patch (renamed from patches/server/0056-Add-exception-reporting-event.patch)14
-rw-r--r--patches/server/0065-Don-t-nest-if-we-don-t-need-to-when-cerealising-text.patch (renamed from patches/server/0057-Don-t-nest-if-we-don-t-need-to-when-cerealising-text.patch)0
-rw-r--r--patches/server/0066-Disable-Scoreboards-for-non-players-by-default.patch (renamed from patches/server/0058-Disable-Scoreboards-for-non-players-by-default.patch)4
-rw-r--r--patches/server/0067-Add-methods-for-working-with-arrows-stuck-in-living-.patch (renamed from patches/server/0059-Add-methods-for-working-with-arrows-stuck-in-living-.patch)0
-rw-r--r--patches/server/0068-Chunk-Save-Reattempt.patch (renamed from patches/server/0060-Chunk-Save-Reattempt.patch)30
-rw-r--r--patches/server/0069-Complete-resource-pack-API.patch (renamed from patches/server/0061-Complete-resource-pack-API.patch)4
-rw-r--r--patches/server/0070-Default-loading-permissions.yml-before-plugins.patch (renamed from patches/server/0062-Default-loading-permissions.yml-before-plugins.patch)2
-rw-r--r--patches/server/0071-Allow-Reloading-of-Custom-Permissions.patch (renamed from patches/server/0063-Allow-Reloading-of-Custom-Permissions.patch)2
-rw-r--r--patches/server/0072-Remove-Metadata-on-reload.patch (renamed from patches/server/0064-Remove-Metadata-on-reload.patch)2
-rw-r--r--patches/server/0073-Handle-Item-Meta-Inconsistencies.patch (renamed from patches/server/0065-Handle-Item-Meta-Inconsistencies.patch)0
-rw-r--r--patches/server/0074-Configurable-Non-Player-Arrow-Despawn-Rate.patch (renamed from patches/server/0066-Configurable-Non-Player-Arrow-Despawn-Rate.patch)0
-rw-r--r--patches/server/0075-Add-World-Util-Methods.patch (renamed from patches/server/0067-Add-World-Util-Methods.patch)2
-rw-r--r--patches/server/0076-Custom-replacement-for-eaten-items.patch (renamed from patches/server/0068-Custom-replacement-for-eaten-items.patch)0
-rw-r--r--patches/server/0077-handle-NaN-health-absorb-values-and-repair-bad-data.patch (renamed from patches/server/0069-handle-NaN-health-absorb-values-and-repair-bad-data.patch)2
-rw-r--r--patches/server/0078-Use-a-Shared-Random-for-Entities.patch (renamed from patches/server/0070-Use-a-Shared-Random-for-Entities.patch)2
-rw-r--r--patches/server/0079-Configurable-spawn-chances-for-skeleton-horses.patch (renamed from patches/server/0071-Configurable-spawn-chances-for-skeleton-horses.patch)4
-rw-r--r--patches/server/0080-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch (renamed from patches/server/0072-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch)2
-rw-r--r--patches/server/0081-Only-process-BlockPhysicsEvent-if-a-plugin-has-a-lis.patch (renamed from patches/server/0073-Only-process-BlockPhysicsEvent-if-a-plugin-has-a-lis.patch)4
-rw-r--r--patches/server/0082-Entity-AddTo-RemoveFrom-World-Events.patch (renamed from patches/server/0074-Entity-AddTo-RemoveFrom-World-Events.patch)6
-rw-r--r--patches/server/0083-Configurable-Chunk-Inhabited-Time.patch (renamed from patches/server/0075-Configurable-Chunk-Inhabited-Time.patch)2
-rw-r--r--patches/server/0084-EntityPathfindEvent.patch (renamed from patches/server/0076-EntityPathfindEvent.patch)0
-rw-r--r--patches/server/0085-Sanitise-RegionFileCache-and-make-configurable.patch (renamed from patches/server/0077-Sanitise-RegionFileCache-and-make-configurable.patch)6
-rw-r--r--patches/server/0086-Do-not-load-chunks-for-Pathfinding.patch (renamed from patches/server/0078-Do-not-load-chunks-for-Pathfinding.patch)0
-rw-r--r--patches/server/0087-Add-PlayerUseUnknownEntityEvent.patch (renamed from patches/server/0079-Add-PlayerUseUnknownEntityEvent.patch)4
-rw-r--r--patches/server/0088-Configurable-Grass-Spread-Tick-Rate.patch (renamed from patches/server/0080-Configurable-Grass-Spread-Tick-Rate.patch)0
-rw-r--r--patches/server/0089-Fix-Cancelling-BlockPlaceEvent-triggering-physics.patch (renamed from patches/server/0081-Fix-Cancelling-BlockPlaceEvent-triggering-physics.patch)4
-rw-r--r--patches/server/0090-Optimize-DataBits.patch (renamed from patches/server/0082-Optimize-DataBits.patch)0
-rw-r--r--patches/server/0091-Option-to-use-vanilla-per-world-scoreboard-coloring-.patch (renamed from patches/server/0083-Option-to-use-vanilla-per-world-scoreboard-coloring-.patch)0
-rw-r--r--patches/server/0092-Configurable-Player-Collision.patch (renamed from patches/server/0084-Configurable-Player-Collision.patch)10
-rw-r--r--patches/server/0093-Add-handshake-event-to-allow-plugins-to-handle-clien.patch (renamed from patches/server/0085-Add-handshake-event-to-allow-plugins-to-handle-clien.patch)0
-rw-r--r--patches/server/0094-Configurable-RCON-IP-address.patch (renamed from patches/server/0086-Configurable-RCON-IP-address.patch)0
-rw-r--r--patches/server/0095-EntityRegainHealthEvent-isFastRegen-API.patch (renamed from patches/server/0087-EntityRegainHealthEvent-isFastRegen-API.patch)0
-rw-r--r--patches/server/0096-Add-ability-to-configure-frosted_ice-properties.patch (renamed from patches/server/0088-Add-ability-to-configure-frosted_ice-properties.patch)0
-rw-r--r--patches/server/0097-remove-null-possibility-for-getServer-singleton.patch (renamed from patches/server/0089-remove-null-possibility-for-getServer-singleton.patch)2
-rw-r--r--patches/server/0098-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch (renamed from patches/server/0090-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch)4
-rw-r--r--patches/server/0099-LootTable-API-Replenishable-Lootables-Feature.patch (renamed from patches/server/0091-LootTable-API-Replenishable-Lootables-Feature.patch)2
-rw-r--r--patches/server/0100-Don-t-save-empty-scoreboard-teams-to-scoreboard.dat.patch (renamed from patches/server/0092-Don-t-save-empty-scoreboard-teams-to-scoreboard.dat.patch)0
-rw-r--r--patches/server/0101-System-property-for-disabling-watchdoge.patch (renamed from patches/server/0093-System-property-for-disabling-watchdoge.patch)2
-rw-r--r--patches/server/0102-Async-GameProfileCache-saving.patch (renamed from patches/server/0094-Async-GameProfileCache-saving.patch)4
-rw-r--r--patches/server/0103-Optional-TNT-doesn-t-move-in-water.patch (renamed from patches/server/0095-Optional-TNT-doesn-t-move-in-water.patch)0
-rw-r--r--patches/server/0104-Faster-redstone-torch-rapid-clock-removal.patch (renamed from patches/server/0096-Faster-redstone-torch-rapid-clock-removal.patch)0
-rw-r--r--patches/server/0105-Add-server-name-parameter.patch (renamed from patches/server/0097-Add-server-name-parameter.patch)2
-rw-r--r--patches/server/0106-Only-send-Dragon-Wither-Death-sounds-to-same-world.patch (renamed from patches/server/0098-Only-send-Dragon-Wither-Death-sounds-to-same-world.patch)0
-rw-r--r--patches/server/0107-Fix-Old-Sign-Conversion.patch (renamed from patches/server/0099-Fix-Old-Sign-Conversion.patch)0
-rw-r--r--patches/server/0108-Avoid-blocking-on-Network-Manager-creation.patch (renamed from patches/server/0100-Avoid-blocking-on-Network-Manager-creation.patch)0
-rw-r--r--patches/server/0109-Don-t-lookup-game-profiles-that-have-no-UUID-and-no-.patch (renamed from patches/server/0101-Don-t-lookup-game-profiles-that-have-no-UUID-and-no-.patch)0
-rw-r--r--patches/server/0110-Add-setting-for-proxy-online-mode-status.patch (renamed from patches/server/0102-Add-setting-for-proxy-online-mode-status.patch)2
-rw-r--r--patches/server/0111-Optimise-BlockState-s-hashCode-equals.patch (renamed from patches/server/0103-Optimise-BlockState-s-hashCode-equals.patch)0
-rw-r--r--patches/server/0112-Configurable-packet-in-spam-threshold.patch (renamed from patches/server/0104-Configurable-packet-in-spam-threshold.patch)4
-rw-r--r--patches/server/0113-Configurable-flying-kick-messages.patch (renamed from patches/server/0105-Configurable-flying-kick-messages.patch)2
-rw-r--r--patches/server/0114-Add-EntityZapEvent.patch (renamed from patches/server/0106-Add-EntityZapEvent.patch)0
-rw-r--r--patches/server/0115-Filter-bad-data-from-ArmorStand-and-SpawnEgg-items.patch (renamed from patches/server/0107-Filter-bad-data-from-ArmorStand-and-SpawnEgg-items.patch)0
-rw-r--r--patches/server/0116-Cache-user-authenticator-threads.patch (renamed from patches/server/0108-Cache-user-authenticator-threads.patch)0
-rw-r--r--patches/server/0117-Allow-Reloading-of-Command-Aliases.patch (renamed from patches/server/0109-Allow-Reloading-of-Command-Aliases.patch)2
-rw-r--r--patches/server/0118-Add-source-to-PlayerExpChangeEvent.patch (renamed from patches/server/0110-Add-source-to-PlayerExpChangeEvent.patch)0
-rw-r--r--patches/server/0119-Add-ProjectileCollideEvent.patch (renamed from patches/server/0111-Add-ProjectileCollideEvent.patch)0
-rw-r--r--patches/server/0120-Prevent-Pathfinding-out-of-World-Border.patch (renamed from patches/server/0112-Prevent-Pathfinding-out-of-World-Border.patch)0
-rw-r--r--patches/server/0121-Optimize-World.isLoaded-BlockPosition-Z.patch (renamed from patches/server/0113-Optimize-World.isLoaded-BlockPosition-Z.patch)0
-rw-r--r--patches/server/0122-Bound-Treasure-Maps-to-World-Border.patch (renamed from patches/server/0114-Bound-Treasure-Maps-to-World-Border.patch)0
-rw-r--r--patches/server/0123-Configurable-Cartographer-Treasure-Maps.patch (renamed from patches/server/0115-Configurable-Cartographer-Treasure-Maps.patch)0
-rw-r--r--patches/server/0124-Optimize-ItemStack.isEmpty.patch (renamed from patches/server/0116-Optimize-ItemStack.isEmpty.patch)0
-rw-r--r--patches/server/0125-Add-API-methods-to-control-if-armour-stands-can-move.patch (renamed from patches/server/0117-Add-API-methods-to-control-if-armour-stands-can-move.patch)0
-rw-r--r--patches/server/0126-String-based-Action-Bar-API.patch (renamed from patches/server/0118-String-based-Action-Bar-API.patch)2
-rw-r--r--patches/server/0127-Properly-fix-item-duplication-bug.patch (renamed from patches/server/0119-Properly-fix-item-duplication-bug.patch)8
-rw-r--r--patches/server/0128-Firework-API-s.patch (renamed from patches/server/0120-Firework-API-s.patch)0
-rw-r--r--patches/server/0129-PlayerTeleportEndGatewayEvent.patch (renamed from patches/server/0121-PlayerTeleportEndGatewayEvent.patch)0
-rw-r--r--patches/server/0130-Provide-E-TE-Chunk-count-stat-methods.patch (renamed from patches/server/0122-Provide-E-TE-Chunk-count-stat-methods.patch)9
-rw-r--r--patches/server/0131-Enforce-Sync-Player-Saves.patch (renamed from patches/server/0123-Enforce-Sync-Player-Saves.patch)4
-rw-r--r--patches/server/0132-Don-t-allow-entities-to-ride-themselves-572.patch (renamed from patches/server/0124-Don-t-allow-entities-to-ride-themselves-572.patch)2
-rw-r--r--patches/server/0133-ExperienceOrbs-API-for-Reason-Source-Triggering-play.patch (renamed from patches/server/0125-ExperienceOrbs-API-for-Reason-Source-Triggering-play.patch)0
-rw-r--r--patches/server/0134-Cap-Entity-Collisions.patch (renamed from patches/server/0126-Cap-Entity-Collisions.patch)2
-rw-r--r--patches/server/0135-Remove-CraftScheduler-Async-Task-Debugger.patch (renamed from patches/server/0127-Remove-CraftScheduler-Async-Task-Debugger.patch)0
-rw-r--r--patches/server/0136-Do-not-let-armorstands-drown.patch (renamed from patches/server/0128-Do-not-let-armorstands-drown.patch)0
-rw-r--r--patches/server/0137-Make-targetSize-more-aggressive-in-the-chunk-unload-.patch (renamed from patches/server/0129-Make-targetSize-more-aggressive-in-the-chunk-unload-.patch)10
-rw-r--r--patches/server/0138-Properly-handle-async-calls-to-restart-the-server.patch (renamed from patches/server/0130-Properly-handle-async-calls-to-restart-the-server.patch)6
-rw-r--r--patches/server/0139-Add-option-to-make-parrots-stay-on-shoulders-despite.patch (renamed from patches/server/0131-Add-option-to-make-parrots-stay-on-shoulders-despite.patch)4
-rw-r--r--patches/server/0140-Add-configuration-option-to-prevent-player-names-fro.patch (renamed from patches/server/0132-Add-configuration-option-to-prevent-player-names-fro.patch)2
-rw-r--r--patches/server/0141-Use-TerminalConsoleAppender-for-console-improvements.patch (renamed from patches/server/0133-Use-TerminalConsoleAppender-for-console-improvements.patch)4
-rw-r--r--patches/server/0142-provide-a-configurable-option-to-disable-creeper-lin.patch (renamed from patches/server/0134-provide-a-configurable-option-to-disable-creeper-lin.patch)0
-rw-r--r--patches/server/0143-Item-canEntityPickup.patch (renamed from patches/server/0135-Item-canEntityPickup.patch)0
-rw-r--r--patches/server/0144-PlayerPickupItemEvent-setFlyAtPlayer.patch (renamed from patches/server/0136-PlayerPickupItemEvent-setFlyAtPlayer.patch)0
-rw-r--r--patches/server/0145-PlayerAttemptPickupItemEvent.patch (renamed from patches/server/0137-PlayerAttemptPickupItemEvent.patch)0
-rw-r--r--patches/server/0146-Do-not-submit-profile-lookups-to-worldgen-threads.patch (renamed from patches/server/0138-Do-not-submit-profile-lookups-to-worldgen-threads.patch)0
-rw-r--r--patches/server/0147-Add-UnknownCommandEvent.patch (renamed from patches/server/0139-Add-UnknownCommandEvent.patch)2
-rw-r--r--patches/server/0148-Basic-PlayerProfile-API.patch (renamed from patches/server/0140-Basic-PlayerProfile-API.patch)18
-rw-r--r--patches/server/0149-Shoulder-Entities-Release-API.patch (renamed from patches/server/0141-Shoulder-Entities-Release-API.patch)0
-rw-r--r--patches/server/0150-Profile-Lookup-Events.patch (renamed from patches/server/0142-Profile-Lookup-Events.patch)0
-rw-r--r--patches/server/0151-Block-player-logins-during-server-shutdown.patch (renamed from patches/server/0143-Block-player-logins-during-server-shutdown.patch)0
-rw-r--r--patches/server/0152-Entity-fromMobSpawner.patch (renamed from patches/server/0144-Entity-fromMobSpawner.patch)6
-rw-r--r--patches/server/0153-Improve-the-Saddle-API-for-Horses.patch (renamed from patches/server/0145-Improve-the-Saddle-API-for-Horses.patch)0
-rw-r--r--patches/server/0154-Implement-ensureServerConversions-API.patch (renamed from patches/server/0146-Implement-ensureServerConversions-API.patch)0
-rw-r--r--patches/server/0155-Implement-getI18NDisplayName.patch (renamed from patches/server/0147-Implement-getI18NDisplayName.patch)0
-rw-r--r--patches/server/0156-ProfileWhitelistVerifyEvent.patch (renamed from patches/server/0148-ProfileWhitelistVerifyEvent.patch)6
-rw-r--r--patches/server/0157-Fix-this-stupid-bullshit.patch (renamed from patches/server/0149-Fix-this-stupid-bullshit.patch)0
-rw-r--r--patches/server/0158-LivingEntity-setKiller.patch (renamed from patches/server/0150-LivingEntity-setKiller.patch)0
-rw-r--r--patches/server/0159-Ocelot-despawns-should-honor-nametags-and-leash.patch (renamed from patches/server/0151-Ocelot-despawns-should-honor-nametags-and-leash.patch)0
-rw-r--r--patches/server/0160-Reset-spawner-timer-when-spawner-event-is-cancelled.patch (renamed from patches/server/0152-Reset-spawner-timer-when-spawner-event-is-cancelled.patch)0
-rw-r--r--patches/server/0161-Allow-specifying-a-custom-authentication-servers-dow.patch (renamed from patches/server/0153-Allow-specifying-a-custom-authentication-servers-dow.patch)0
-rw-r--r--patches/server/0162-Handle-plugin-prefixes-using-Log4J-configuration.patch (renamed from patches/server/0154-Handle-plugin-prefixes-using-Log4J-configuration.patch)0
-rw-r--r--patches/server/0163-Improve-Log4J-Configuration-Plugin-Loggers.patch (renamed from patches/server/0155-Improve-Log4J-Configuration-Plugin-Loggers.patch)0
-rw-r--r--patches/server/0164-Add-PlayerJumpEvent.patch (renamed from patches/server/0156-Add-PlayerJumpEvent.patch)4
-rw-r--r--patches/server/0165-handle-ServerboundKeepAlivePacket-async.patch (renamed from patches/server/0157-handle-ServerboundKeepAlivePacket-async.patch)4
-rw-r--r--patches/server/0166-Expose-client-protocol-version-and-virtual-host.patch (renamed from patches/server/0158-Expose-client-protocol-version-and-virtual-host.patch)4
-rw-r--r--patches/server/0167-revert-serverside-behavior-of-keepalives.patch (renamed from patches/server/0159-revert-serverside-behavior-of-keepalives.patch)2
-rw-r--r--patches/server/0168-Send-attack-SoundEffects-only-to-players-who-can-see.patch (renamed from patches/server/0160-Send-attack-SoundEffects-only-to-players-who-can-see.patch)0
-rw-r--r--patches/server/0169-Add-PlayerArmorChangeEvent.patch (renamed from patches/server/0161-Add-PlayerArmorChangeEvent.patch)0
-rw-r--r--patches/server/0170-Prevent-logins-from-being-processed-when-the-player-.patch (renamed from patches/server/0162-Prevent-logins-from-being-processed-when-the-player-.patch)0
-rw-r--r--patches/server/0171-Fix-MC-117075-TE-Unload-Lag-Spike.patch (renamed from patches/server/0163-Fix-MC-117075-TE-Unload-Lag-Spike.patch)0
-rw-r--r--patches/server/0172-use-CB-BlockState-implementations-for-captured-block.patch (renamed from patches/server/0164-use-CB-BlockState-implementations-for-captured-block.patch)0
-rw-r--r--patches/server/0173-API-to-get-a-BlockState-without-a-snapshot.patch (renamed from patches/server/0165-API-to-get-a-BlockState-without-a-snapshot.patch)0
-rw-r--r--patches/server/0174-AsyncTabCompleteEvent.patch (renamed from patches/server/0166-AsyncTabCompleteEvent.patch)8
-rw-r--r--patches/server/0175-PlayerPickupExperienceEvent.patch (renamed from patches/server/0167-PlayerPickupExperienceEvent.patch)0
-rw-r--r--patches/server/0176-Ability-to-apply-mending-to-XP-API.patch (renamed from patches/server/0168-Ability-to-apply-mending-to-XP-API.patch)2
-rw-r--r--patches/server/0177-PlayerNaturallySpawnCreaturesEvent.patch (renamed from patches/server/0169-PlayerNaturallySpawnCreaturesEvent.patch)14
-rw-r--r--patches/server/0178-Add-setPlayerProfile-API-for-Skulls.patch (renamed from patches/server/0170-Add-setPlayerProfile-API-for-Skulls.patch)0
-rw-r--r--patches/server/0179-PreCreatureSpawnEvent.patch (renamed from patches/server/0171-PreCreatureSpawnEvent.patch)0
-rw-r--r--patches/server/0180-Fill-Profile-Property-Events.patch (renamed from patches/server/0172-Fill-Profile-Property-Events.patch)0
-rw-r--r--patches/server/0181-PlayerAdvancementCriterionGrantEvent.patch (renamed from patches/server/0173-PlayerAdvancementCriterionGrantEvent.patch)0
-rw-r--r--patches/server/0182-Add-ArmorStand-Item-Meta.patch (renamed from patches/server/0174-Add-ArmorStand-Item-Meta.patch)0
-rw-r--r--patches/server/0183-Extend-Player-Interact-cancellation.patch (renamed from patches/server/0175-Extend-Player-Interact-cancellation.patch)0
-rw-r--r--patches/server/0184-Tameable-getOwnerUniqueId-API.patch (renamed from patches/server/0176-Tameable-getOwnerUniqueId-API.patch)0
-rw-r--r--patches/server/0185-Toggleable-player-crits-helps-mitigate-hacked-client.patch (renamed from patches/server/0177-Toggleable-player-crits-helps-mitigate-hacked-client.patch)0
-rw-r--r--patches/server/0186-Disable-Explicit-Network-Manager-Flushing.patch (renamed from patches/server/0178-Disable-Explicit-Network-Manager-Flushing.patch)2
-rw-r--r--patches/server/0187-Implement-extended-PaperServerListPingEvent.patch (renamed from patches/server/0179-Implement-extended-PaperServerListPingEvent.patch)2
-rw-r--r--patches/server/0188-Ability-to-change-PlayerProfile-in-AsyncPreLoginEven.patch (renamed from patches/server/0180-Ability-to-change-PlayerProfile-in-AsyncPreLoginEven.patch)0
-rw-r--r--patches/server/0189-Player.setPlayerProfile-API.patch (renamed from patches/server/0181-Player.setPlayerProfile-API.patch)0
-rw-r--r--patches/server/0190-getPlayerUniqueId-API.patch (renamed from patches/server/0182-getPlayerUniqueId-API.patch)2
-rw-r--r--patches/server/0191-Improved-Async-Task-Scheduler.patch (renamed from patches/server/0183-Improved-Async-Task-Scheduler.patch)0
-rw-r--r--patches/server/0192-Make-legacy-ping-handler-more-reliable.patch (renamed from patches/server/0184-Make-legacy-ping-handler-more-reliable.patch)0
-rw-r--r--patches/server/0193-Call-PaperServerListPingEvent-for-legacy-pings.patch (renamed from patches/server/0185-Call-PaperServerListPingEvent-for-legacy-pings.patch)0
-rw-r--r--patches/server/0194-Flag-to-disable-the-channel-limit.patch (renamed from patches/server/0186-Flag-to-disable-the-channel-limit.patch)2
-rw-r--r--patches/server/0195-Add-openSign-method-to-HumanEntity.patch (renamed from patches/server/0187-Add-openSign-method-to-HumanEntity.patch)0
-rw-r--r--patches/server/0196-Configurable-sprint-interruption-on-attack.patch (renamed from patches/server/0188-Configurable-sprint-interruption-on-attack.patch)0
-rw-r--r--patches/server/0197-Fix-exploit-that-allowed-colored-signs-to-be-created.patch (renamed from patches/server/0189-Fix-exploit-that-allowed-colored-signs-to-be-created.patch)4
-rw-r--r--patches/server/0198-EndermanEscapeEvent.patch (renamed from patches/server/0190-EndermanEscapeEvent.patch)0
-rw-r--r--patches/server/0199-Enderman.teleportRandomly.patch (renamed from patches/server/0191-Enderman.teleportRandomly.patch)0
-rw-r--r--patches/server/0200-Block-Enderpearl-Travel-Exploit.patch (renamed from patches/server/0192-Block-Enderpearl-Travel-Exploit.patch)4
-rw-r--r--patches/server/0201-Expand-World.spawnParticle-API-and-add-Builder.patch (renamed from patches/server/0193-Expand-World.spawnParticle-API-and-add-Builder.patch)8
-rw-r--r--patches/server/0202-Prevent-Frosted-Ice-from-loading-holding-chunks.patch (renamed from patches/server/0194-Prevent-Frosted-Ice-from-loading-holding-chunks.patch)0
-rw-r--r--patches/server/0203-EndermanAttackPlayerEvent.patch (renamed from patches/server/0195-EndermanAttackPlayerEvent.patch)0
-rw-r--r--patches/server/0204-WitchConsumePotionEvent.patch (renamed from patches/server/0196-WitchConsumePotionEvent.patch)0
-rw-r--r--patches/server/0205-WitchThrowPotionEvent.patch (renamed from patches/server/0197-WitchThrowPotionEvent.patch)0
-rw-r--r--patches/server/0206-Allow-spawning-Item-entities-with-World.spawnEntity.patch (renamed from patches/server/0198-Allow-spawning-Item-entities-with-World.spawnEntity.patch)0
-rw-r--r--patches/server/0207-WitchReadyPotionEvent.patch (renamed from patches/server/0199-WitchReadyPotionEvent.patch)0
-rw-r--r--patches/server/0208-ItemStack-getMaxItemUseDuration.patch (renamed from patches/server/0200-ItemStack-getMaxItemUseDuration.patch)0
-rw-r--r--patches/server/0209-Implement-EntityTeleportEndGatewayEvent.patch (renamed from patches/server/0201-Implement-EntityTeleportEndGatewayEvent.patch)0
-rw-r--r--patches/server/0210-Unset-Ignited-flag-on-cancel-of-Explosion-Event.patch (renamed from patches/server/0202-Unset-Ignited-flag-on-cancel-of-Explosion-Event.patch)0
-rw-r--r--patches/server/0211-Fix-CraftEntity-hashCode.patch (renamed from patches/server/0203-Fix-CraftEntity-hashCode.patch)2
-rw-r--r--patches/server/0212-Configurable-Alternative-LootPool-Luck-Formula.patch (renamed from patches/server/0204-Configurable-Alternative-LootPool-Luck-Formula.patch)0
-rw-r--r--patches/server/0213-Print-Error-details-when-failing-to-save-player-data.patch (renamed from patches/server/0205-Print-Error-details-when-failing-to-save-player-data.patch)0
-rw-r--r--patches/server/0214-Make-shield-blocking-delay-configurable.patch (renamed from patches/server/0206-Make-shield-blocking-delay-configurable.patch)0
-rw-r--r--patches/server/0215-Improve-EntityShootBowEvent.patch (renamed from patches/server/0207-Improve-EntityShootBowEvent.patch)0
-rw-r--r--patches/server/0216-PlayerReadyArrowEvent.patch (renamed from patches/server/0208-PlayerReadyArrowEvent.patch)0
-rw-r--r--patches/server/0217-Implement-EntityKnockbackByEntityEvent.patch (renamed from patches/server/0209-Implement-EntityKnockbackByEntityEvent.patch)0
-rw-r--r--patches/server/0218-Expand-Explosions-API.patch (renamed from patches/server/0210-Expand-Explosions-API.patch)4
-rw-r--r--patches/server/0219-LivingEntity-Hand-Raised-Item-Use-API.patch (renamed from patches/server/0211-LivingEntity-Hand-Raised-Item-Use-API.patch)0
-rw-r--r--patches/server/0220-RangedEntity-API.patch (renamed from patches/server/0212-RangedEntity-API.patch)0
-rw-r--r--patches/server/0221-Add-config-to-disable-ender-dragon-legacy-check.patch (renamed from patches/server/0213-Add-config-to-disable-ender-dragon-legacy-check.patch)0
-rw-r--r--patches/server/0222-Implement-World.getEntity-UUID-API.patch (renamed from patches/server/0214-Implement-World.getEntity-UUID-API.patch)4
-rw-r--r--patches/server/0223-InventoryCloseEvent-Reason-API.patch (renamed from patches/server/0215-InventoryCloseEvent-Reason-API.patch)24
-rw-r--r--patches/server/0224-Vex-get-setSummoner-API.patch (renamed from patches/server/0216-Vex-get-setSummoner-API.patch)0
-rw-r--r--patches/server/0225-Refresh-player-inventory-when-cancelling-PlayerInter.patch (renamed from patches/server/0217-Refresh-player-inventory-when-cancelling-PlayerInter.patch)4
-rw-r--r--patches/server/0226-Use-AsyncAppender-to-keep-logging-IO-off-main-thread.patch (renamed from patches/server/0218-Use-AsyncAppender-to-keep-logging-IO-off-main-thread.patch)0
-rw-r--r--patches/server/0227-add-more-information-to-Entity.toString.patch (renamed from patches/server/0219-add-more-information-to-Entity.toString.patch)2
-rw-r--r--patches/server/0228-Add-CraftMagicNumbers.isSupportedApiVersion.patch (renamed from patches/server/0220-Add-CraftMagicNumbers.isSupportedApiVersion.patch)2
-rw-r--r--patches/server/0229-EnderDragon-Events.patch (renamed from patches/server/0221-EnderDragon-Events.patch)0
-rw-r--r--patches/server/0230-PlayerElytraBoostEvent.patch (renamed from patches/server/0222-PlayerElytraBoostEvent.patch)0
-rw-r--r--patches/server/0231-PlayerLaunchProjectileEvent.patch (renamed from patches/server/0223-PlayerLaunchProjectileEvent.patch)0
-rw-r--r--patches/server/0232-Improve-BlockPosition-inlining.patch (renamed from patches/server/0224-Improve-BlockPosition-inlining.patch)0
-rw-r--r--patches/server/0233-Option-to-prevent-armor-stands-from-doing-entity-loo.patch (renamed from patches/server/0225-Option-to-prevent-armor-stands-from-doing-entity-loo.patch)0
-rw-r--r--patches/server/0234-Vanished-players-don-t-have-rights.patch (renamed from patches/server/0226-Vanished-players-don-t-have-rights.patch)0
-rw-r--r--patches/server/0235-Allow-disabling-armour-stand-ticking.patch (renamed from patches/server/0227-Allow-disabling-armour-stand-ticking.patch)0
-rw-r--r--patches/server/0236-SkeletonHorse-Additions.patch (renamed from patches/server/0228-SkeletonHorse-Additions.patch)0
-rw-r--r--patches/server/0237-Don-t-call-getItemMeta-on-hasItemMeta.patch (renamed from patches/server/0229-Don-t-call-getItemMeta-on-hasItemMeta.patch)0
-rw-r--r--patches/server/0238-Implement-Expanded-ArmorStand-API.patch (renamed from patches/server/0230-Implement-Expanded-ArmorStand-API.patch)0
-rw-r--r--patches/server/0239-AnvilDamageEvent.patch (renamed from patches/server/0231-AnvilDamageEvent.patch)0
-rw-r--r--patches/server/0240-Add-hand-to-bucket-events.patch (renamed from patches/server/0232-Add-hand-to-bucket-events.patch)0
-rw-r--r--patches/server/0241-Add-TNTPrimeEvent.patch (renamed from patches/server/0233-Add-TNTPrimeEvent.patch)0
-rw-r--r--patches/server/0242-Break-up-and-make-tab-spam-limits-configurable.patch (renamed from patches/server/0234-Break-up-and-make-tab-spam-limits-configurable.patch)2
-rw-r--r--patches/server/0243-MC-135506-Experience-should-save-as-Integers.patch (renamed from patches/server/0235-MC-135506-Experience-should-save-as-Integers.patch)0
-rw-r--r--patches/server/0244-Remove-unnecessary-itemmeta-handling.patch (renamed from patches/server/0236-Remove-unnecessary-itemmeta-handling.patch)0
-rw-r--r--patches/server/0245-Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch (renamed from patches/server/0237-Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch)12
-rw-r--r--patches/server/0246-Add-Early-Warning-Feature-to-WatchDog.patch (renamed from patches/server/0238-Add-Early-Warning-Feature-to-WatchDog.patch)9
-rw-r--r--patches/server/0247-Use-ConcurrentHashMap-in-JsonList.patch (renamed from patches/server/0239-Use-ConcurrentHashMap-in-JsonList.patch)4
-rw-r--r--patches/server/0248-Use-a-Queue-for-Queueing-Commands.patch (renamed from patches/server/0240-Use-a-Queue-for-Queueing-Commands.patch)0
-rw-r--r--patches/server/0249-Ability-to-get-Tile-Entities-from-a-chunk-without-sn.patch (renamed from patches/server/0241-Ability-to-get-Tile-Entities-from-a-chunk-without-sn.patch)0
-rw-r--r--patches/server/0250-Optimize-BlockPosition-helper-methods.patch (renamed from patches/server/0242-Optimize-BlockPosition-helper-methods.patch)0
-rw-r--r--patches/server/0251-Restore-vanilla-default-mob-spawn-range-and-water-an.patch (renamed from patches/server/0243-Restore-vanilla-default-mob-spawn-range-and-water-an.patch)0
-rw-r--r--patches/server/0252-Slime-Pathfinder-Events.patch (renamed from patches/server/0244-Slime-Pathfinder-Events.patch)0
-rw-r--r--patches/server/0253-Configurable-speed-for-water-flowing-over-lava.patch (renamed from patches/server/0245-Configurable-speed-for-water-flowing-over-lava.patch)0
-rw-r--r--patches/server/0254-Optimize-CraftBlockData-Creation.patch (renamed from patches/server/0246-Optimize-CraftBlockData-Creation.patch)0
-rw-r--r--patches/server/0255-Optimize-MappedRegistry.patch (renamed from patches/server/0247-Optimize-MappedRegistry.patch)0
-rw-r--r--patches/server/0256-Add-PhantomPreSpawnEvent.patch (renamed from patches/server/0248-Add-PhantomPreSpawnEvent.patch)0
-rw-r--r--patches/server/0257-Add-More-Creeper-API.patch (renamed from patches/server/0249-Add-More-Creeper-API.patch)2
-rw-r--r--patches/server/0258-Inventory-removeItemAnySlot.patch (renamed from patches/server/0250-Inventory-removeItemAnySlot.patch)0
-rw-r--r--patches/server/0259-Make-CraftWorld-loadChunk-int-int-false-load-unconve.patch (renamed from patches/server/0251-Make-CraftWorld-loadChunk-int-int-false-load-unconve.patch)4
-rw-r--r--patches/server/0260-Add-ray-tracing-methods-to-LivingEntity.patch (renamed from patches/server/0253-Add-ray-tracing-methods-to-LivingEntity.patch)4
-rw-r--r--patches/server/0261-Expose-attack-cooldown-methods-for-Player.patch (renamed from patches/server/0254-Expose-attack-cooldown-methods-for-Player.patch)2
-rw-r--r--patches/server/0262-Improve-death-events.patch (renamed from patches/server/0255-Improve-death-events.patch)10
-rw-r--r--patches/server/0263-Allow-chests-to-be-placed-with-NBT-data.patch (renamed from patches/server/0256-Allow-chests-to-be-placed-with-NBT-data.patch)0
-rw-r--r--patches/server/0264-Mob-Pathfinding-API.patch (renamed from patches/server/0257-Mob-Pathfinding-API.patch)0
-rw-r--r--patches/server/0265-Implement-an-API-for-CanPlaceOn-and-CanDestroy-NBT-v.patch (renamed from patches/server/0258-Implement-an-API-for-CanPlaceOn-and-CanDestroy-NBT-v.patch)0
-rw-r--r--patches/server/0266-Prevent-chunk-loading-from-Fluid-Flowing.patch (renamed from patches/server/0259-Prevent-chunk-loading-from-Fluid-Flowing.patch)0
-rw-r--r--patches/server/0267-Prevent-Mob-AI-Rules-from-Loading-Chunks.patch (renamed from patches/server/0260-Prevent-Mob-AI-Rules-from-Loading-Chunks.patch)0
-rw-r--r--patches/server/0268-Prevent-mob-spawning-from-loading-generating-chunks.patch (renamed from patches/server/0261-Prevent-mob-spawning-from-loading-generating-chunks.patch)0
-rw-r--r--patches/server/0269-Implement-furnace-cook-speed-multiplier-API.patch (renamed from patches/server/0262-Implement-furnace-cook-speed-multiplier-API.patch)0
-rw-r--r--patches/server/0270-Catch-JsonParseException-in-Entity-and-TE-names.patch (renamed from patches/server/0263-Catch-JsonParseException-in-Entity-and-TE-names.patch)16
-rw-r--r--patches/server/0271-Honor-EntityAgeable.ageLock.patch (renamed from patches/server/0264-Honor-EntityAgeable.ageLock.patch)0
-rw-r--r--patches/server/0272-Configurable-connection-throttle-kick-message.patch (renamed from patches/server/0265-Configurable-connection-throttle-kick-message.patch)0
-rw-r--r--patches/server/0273-Hook-into-CB-plugin-rewrites.patch (renamed from patches/server/0266-Hook-into-CB-plugin-rewrites.patch)0
-rw-r--r--patches/server/0274-PreSpawnerSpawnEvent.patch (renamed from patches/server/0267-PreSpawnerSpawnEvent.patch)0
-rw-r--r--patches/server/0275-Add-LivingEntity-getTargetEntity.patch (renamed from patches/server/0268-Add-LivingEntity-getTargetEntity.patch)0
-rw-r--r--patches/server/0276-Add-sun-related-API.patch (renamed from patches/server/0269-Add-sun-related-API.patch)4
-rw-r--r--patches/server/0277-Turtle-API.patch (renamed from patches/server/0270-Turtle-API.patch)0
-rw-r--r--patches/server/0278-Call-player-spectator-target-events-and-improve-impl.patch (renamed from patches/server/0271-Call-player-spectator-target-events-and-improve-impl.patch)4
-rw-r--r--patches/server/0279-MC-50319-Check-other-worlds-for-shooter-of-projectil.patch (renamed from patches/server/0272-MC-50319-Check-other-worlds-for-shooter-of-projectil.patch)0
-rw-r--r--patches/server/0280-Add-more-Witch-API.patch (renamed from patches/server/0273-Add-more-Witch-API.patch)0
-rw-r--r--patches/server/0281-Check-Drowned-for-Villager-Aggression-Config.patch (renamed from patches/server/0274-Check-Drowned-for-Villager-Aggression-Config.patch)0
-rw-r--r--patches/server/0282-Add-option-to-prevent-players-from-moving-into-unloa.patch (renamed from patches/server/0275-Add-option-to-prevent-players-from-moving-into-unloa.patch)0
-rw-r--r--patches/server/0283-Reset-players-airTicks-on-respawn.patch (renamed from patches/server/0276-Reset-players-airTicks-on-respawn.patch)4
-rw-r--r--patches/server/0284-Don-t-sleep-after-profile-lookups-if-not-needed.patch (renamed from patches/server/0277-Don-t-sleep-after-profile-lookups-if-not-needed.patch)0
-rw-r--r--patches/server/0285-Improve-Server-Thread-Pool-and-Thread-Priorities.patch (renamed from patches/server/0278-Improve-Server-Thread-Pool-and-Thread-Priorities.patch)2
-rw-r--r--patches/server/0286-Optimize-World-Time-Updates.patch (renamed from patches/server/0279-Optimize-World-Time-Updates.patch)2
-rw-r--r--patches/server/0287-Restore-custom-InventoryHolder-support.patch (renamed from patches/server/0280-Restore-custom-InventoryHolder-support.patch)0
-rw-r--r--patches/server/0288-Use-Vanilla-Minecart-Speeds.patch (renamed from patches/server/0281-Use-Vanilla-Minecart-Speeds.patch)0
-rw-r--r--patches/server/0289-Fix-SpongeAbsortEvent-handling.patch (renamed from patches/server/0282-Fix-SpongeAbsortEvent-handling.patch)0
-rw-r--r--patches/server/0290-Don-t-allow-digging-into-unloaded-chunks.patch (renamed from patches/server/0283-Don-t-allow-digging-into-unloaded-chunks.patch)0
-rw-r--r--patches/server/0291-Make-the-default-permission-message-configurable.patch (renamed from patches/server/0284-Make-the-default-permission-message-configurable.patch)6
-rw-r--r--patches/server/0292-Prevent-rayTrace-from-loading-chunks.patch (renamed from patches/server/0285-Prevent-rayTrace-from-loading-chunks.patch)0
-rw-r--r--patches/server/0293-Handle-Large-Packets-disconnecting-client.patch (renamed from patches/server/0286-Handle-Large-Packets-disconnecting-client.patch)0
-rw-r--r--patches/server/0294-force-entity-dismount-during-teleportation.patch (renamed from patches/server/0287-force-entity-dismount-during-teleportation.patch)6
-rw-r--r--patches/server/0295-Add-more-Zombie-API.patch (renamed from patches/server/0288-Add-more-Zombie-API.patch)0
-rw-r--r--patches/server/0296-Book-Size-Limits.patch (renamed from patches/server/0289-Book-Size-Limits.patch)0
-rw-r--r--patches/server/0297-Add-PlayerConnectionCloseEvent.patch (renamed from patches/server/0290-Add-PlayerConnectionCloseEvent.patch)0
-rw-r--r--patches/server/0298-Prevent-Enderman-from-loading-chunks.patch (renamed from patches/server/0291-Prevent-Enderman-from-loading-chunks.patch)0
-rw-r--r--patches/server/0299-Add-APIs-to-replace-OfflinePlayer-getLastPlayed.patch (renamed from patches/server/0292-Add-APIs-to-replace-OfflinePlayer-getLastPlayed.patch)12
-rw-r--r--patches/server/0300-Workaround-for-vehicle-tracking-issue-on-disconnect.patch (renamed from patches/server/0293-Workaround-for-vehicle-tracking-issue-on-disconnect.patch)4
-rw-r--r--patches/server/0301-Block-Entity-remove-from-being-called-on-Players.patch (renamed from patches/server/0294-Block-Entity-remove-from-being-called-on-Players.patch)2
-rw-r--r--patches/server/0302-BlockDestroyEvent.patch (renamed from patches/server/0295-BlockDestroyEvent.patch)0
-rw-r--r--patches/server/0303-Async-command-map-building.patch (renamed from patches/server/0296-Async-command-map-building.patch)2
-rw-r--r--patches/server/0304-Implement-Brigadier-Mojang-API.patch (renamed from patches/server/0297-Implement-Brigadier-Mojang-API.patch)0
-rw-r--r--patches/server/0305-Fix-Custom-Shapeless-Custom-Crafting-Recipes.patch (renamed from patches/server/0298-Fix-Custom-Shapeless-Custom-Crafting-Recipes.patch)0
-rw-r--r--patches/server/0306-Limit-Client-Sign-length-more.patch (renamed from patches/server/0299-Limit-Client-Sign-length-more.patch)0
-rw-r--r--patches/server/0307-Don-t-check-ConvertSigns-boolean-every-sign-save.patch (renamed from patches/server/0300-Don-t-check-ConvertSigns-boolean-every-sign-save.patch)0
-rw-r--r--patches/server/0308-Optimize-Network-Manager-and-add-advanced-packet-sup.patch (renamed from patches/server/0301-Optimize-Network-Manager-and-add-advanced-packet-sup.patch)0
-rw-r--r--patches/server/0309-Handle-Oversized-Tile-Entities-in-chunks.patch (renamed from patches/server/0302-Handle-Oversized-Tile-Entities-in-chunks.patch)0
-rw-r--r--patches/server/0310-Set-Zombie-last-tick-at-start-of-drowning-process.patch (renamed from patches/server/0303-Set-Zombie-last-tick-at-start-of-drowning-process.patch)0
-rw-r--r--patches/server/0311-Call-WhitelistToggleEvent-when-whitelist-is-toggled.patch (renamed from patches/server/0304-Call-WhitelistToggleEvent-when-whitelist-is-toggled.patch)4
-rw-r--r--patches/server/0312-Entity-getEntitySpawnReason.patch (renamed from patches/server/0305-Entity-getEntitySpawnReason.patch)12
-rw-r--r--patches/server/0313-Update-entity-Metadata-for-all-tracked-players.patch (renamed from patches/server/0306-Update-entity-Metadata-for-all-tracked-players.patch)0
-rw-r--r--patches/server/0314-Fire-event-on-GS4-query.patch (renamed from patches/server/0307-Fire-event-on-GS4-query.patch)0
-rw-r--r--patches/server/0315-Implement-PlayerPostRespawnEvent.patch (renamed from patches/server/0308-Implement-PlayerPostRespawnEvent.patch)8
-rw-r--r--patches/server/0316-don-t-go-below-0-for-pickupDelay-breaks-picking-up-i.patch (renamed from patches/server/0309-don-t-go-below-0-for-pickupDelay-breaks-picking-up-i.patch)0
-rw-r--r--patches/server/0317-Server-Tick-Events.patch (renamed from patches/server/0310-Server-Tick-Events.patch)2
-rw-r--r--patches/server/0318-PlayerDeathEvent-getItemsToKeep.patch (renamed from patches/server/0311-PlayerDeathEvent-getItemsToKeep.patch)6
-rw-r--r--patches/server/0319-Optimize-Captured-TileEntity-Lookup.patch (renamed from patches/server/0312-Optimize-Captured-TileEntity-Lookup.patch)0
-rw-r--r--patches/server/0320-Add-Heightmap-API.patch (renamed from patches/server/0313-Add-Heightmap-API.patch)4
-rw-r--r--patches/server/0321-Mob-Spawner-API-Enhancements.patch (renamed from patches/server/0314-Mob-Spawner-API-Enhancements.patch)0
-rw-r--r--patches/server/0322-Fix-CB-call-to-changed-postToMainThread-method.patch (renamed from patches/server/0315-Fix-CB-call-to-changed-postToMainThread-method.patch)0
-rw-r--r--patches/server/0323-Fix-sounds-when-item-frames-are-modified-MC-123450.patch (renamed from patches/server/0316-Fix-sounds-when-item-frames-are-modified-MC-123450.patch)0
-rw-r--r--patches/server/0324-Fix-CraftServer-isPrimaryThread-and-MinecraftServer-.patch (renamed from patches/server/0317-Fix-CraftServer-isPrimaryThread-and-MinecraftServer-.patch)0
-rw-r--r--patches/server/0325-Implement-CraftBlockSoundGroup.patch (renamed from patches/server/0318-Implement-CraftBlockSoundGroup.patch)0
-rw-r--r--patches/server/0326-Configurable-Keep-Spawn-Loaded-range-per-world.patch (renamed from patches/server/0319-Configurable-Keep-Spawn-Loaded-range-per-world.patch)10
-rw-r--r--patches/server/0327-Allow-Saving-of-Oversized-Chunks.patch (renamed from patches/server/0322-Allow-Saving-of-Oversized-Chunks.patch)2
-rw-r--r--patches/server/0328-Expose-the-internal-current-tick.patch (renamed from patches/server/0323-Expose-the-internal-current-tick.patch)2
-rw-r--r--patches/server/0329-Fix-World-isChunkGenerated-calls.patch (renamed from patches/server/0324-Fix-World-isChunkGenerated-calls.patch)14
-rw-r--r--patches/server/0330-Show-blockstate-location-if-we-failed-to-read-it.patch (renamed from patches/server/0325-Show-blockstate-location-if-we-failed-to-read-it.patch)0
-rw-r--r--patches/server/0331-Only-count-Natural-Spawned-mobs-towards-natural-spaw.patch (renamed from patches/server/0326-Only-count-Natural-Spawned-mobs-towards-natural-spaw.patch)0
-rw-r--r--patches/server/0332-Configurable-projectile-relative-velocity.patch (renamed from patches/server/0327-Configurable-projectile-relative-velocity.patch)0
-rw-r--r--patches/server/0333-offset-item-frame-ticking.patch (renamed from patches/server/0328-offset-item-frame-ticking.patch)0
-rw-r--r--patches/server/0334-Fix-MC-158900.patch (renamed from patches/server/0329-Fix-MC-158900.patch)4
-rw-r--r--patches/server/0335-Prevent-consuming-the-wrong-itemstack.patch (renamed from patches/server/0330-Prevent-consuming-the-wrong-itemstack.patch)0
-rw-r--r--patches/server/0336-Dont-send-unnecessary-sign-update.patch (renamed from patches/server/0331-Dont-send-unnecessary-sign-update.patch)0
-rw-r--r--patches/server/0337-Add-option-to-disable-pillager-patrols.patch (renamed from patches/server/0332-Add-option-to-disable-pillager-patrols.patch)0
-rw-r--r--patches/server/0338-Fix-AssertionError-when-player-hand-set-to-empty-typ.patch (renamed from patches/server/0333-Fix-AssertionError-when-player-hand-set-to-empty-typ.patch)0
-rw-r--r--patches/server/0339-Flat-bedrock-generator-settings.patch (renamed from patches/server/0334-Flat-bedrock-generator-settings.patch)0
-rw-r--r--patches/server/0340-Prevent-sync-chunk-loads-when-villagers-try-to-find-.patch (renamed from patches/server/0335-Prevent-sync-chunk-loads-when-villagers-try-to-find-.patch)0
-rw-r--r--patches/server/0341-MC-145656-Fix-Follow-Range-Initial-Target.patch (renamed from patches/server/0336-MC-145656-Fix-Follow-Range-Initial-Target.patch)0
-rw-r--r--patches/server/0342-Duplicate-UUID-Resolve-Option.patch (renamed from patches/server/0337-Duplicate-UUID-Resolve-Option.patch)37
-rw-r--r--patches/server/0343-Optimize-Hoppers.patch (renamed from patches/server/0338-Optimize-Hoppers.patch)2
-rw-r--r--patches/server/0344-PlayerDeathEvent-shouldDropExperience.patch (renamed from patches/server/0339-PlayerDeathEvent-shouldDropExperience.patch)4
-rw-r--r--patches/server/0345-Prevent-bees-loading-chunks-checking-hive-position.patch (renamed from patches/server/0340-Prevent-bees-loading-chunks-checking-hive-position.patch)0
-rw-r--r--patches/server/0346-Don-t-load-Chunks-from-Hoppers-and-other-things.patch (renamed from patches/server/0341-Don-t-load-Chunks-from-Hoppers-and-other-things.patch)0
-rw-r--r--patches/server/0347-Guard-against-serializing-mismatching-chunk-coordina.patch (renamed from patches/server/0342-Guard-against-serializing-mismatching-chunk-coordina.patch)0
-rw-r--r--patches/server/0348-Optimise-IEntityAccess-getPlayerByUUID.patch (renamed from patches/server/0343-Optimise-IEntityAccess-getPlayerByUUID.patch)4
-rw-r--r--patches/server/0349-Fix-items-not-falling-correctly.patch (renamed from patches/server/0344-Fix-items-not-falling-correctly.patch)0
-rw-r--r--patches/server/0350-Lag-compensate-eating.patch (renamed from patches/server/0345-Lag-compensate-eating.patch)0
-rw-r--r--patches/server/0351-Optimize-call-to-getFluid-for-explosions.patch (renamed from patches/server/0346-Optimize-call-to-getFluid-for-explosions.patch)0
-rw-r--r--patches/server/0352-Fix-last-firework-in-stack-not-having-effects-when-d.patch (renamed from patches/server/0347-Fix-last-firework-in-stack-not-having-effects-when-d.patch)0
-rw-r--r--patches/server/0353-Add-effect-to-block-break-naturally.patch (renamed from patches/server/0348-Add-effect-to-block-break-naturally.patch)0
-rw-r--r--patches/server/0354-Entity-Activation-Range-2.0.patch (renamed from patches/server/0349-Entity-Activation-Range-2.0.patch)14
-rw-r--r--patches/server/0355-Increase-Light-Queue-Size.patch (renamed from patches/server/0350-Increase-Light-Queue-Size.patch)2
-rw-r--r--patches/server/0356-Fix-Light-Command.patch (renamed from patches/server/0351-Fix-Light-Command.patch)6
-rw-r--r--patches/server/0357-Anti-Xray.patch (renamed from patches/server/0352-Anti-Xray.patch)22
-rw-r--r--patches/server/0358-Implement-alternative-item-despawn-rate.patch (renamed from patches/server/0353-Implement-alternative-item-despawn-rate.patch)0
-rw-r--r--patches/server/0359-Tracking-Range-Improvements.patch (renamed from patches/server/0354-Tracking-Range-Improvements.patch)4
-rw-r--r--patches/server/0360-Fix-items-vanishing-through-end-portal.patch (renamed from patches/server/0355-Fix-items-vanishing-through-end-portal.patch)2
-rw-r--r--patches/server/0361-implement-optional-per-player-mob-spawns.patch (renamed from patches/server/0356-implement-optional-per-player-mob-spawns.patch)35
-rw-r--r--patches/server/0362-Avoid-hopper-searches-if-there-are-no-items.patch (renamed from patches/server/0357-Avoid-hopper-searches-if-there-are-no-items.patch)0
-rw-r--r--patches/server/0363-Bees-get-gravity-in-void.-Fixes-MC-167279.patch (renamed from patches/server/0358-Bees-get-gravity-in-void.-Fixes-MC-167279.patch)0
-rw-r--r--patches/server/0364-Optimise-getChunkAt-calls-for-loaded-chunks.patch (renamed from patches/server/0359-Optimise-getChunkAt-calls-for-loaded-chunks.patch)6
-rw-r--r--patches/server/0365-Add-debug-for-sync-chunk-loads.patch (renamed from patches/server/0360-Add-debug-for-sync-chunk-loads.patch)8
-rw-r--r--patches/server/0366-Remove-garbage-Java-version-check.patch (renamed from patches/server/0361-Remove-garbage-Java-version-check.patch)0
-rw-r--r--patches/server/0367-Add-ThrownEggHatchEvent.patch (renamed from patches/server/0362-Add-ThrownEggHatchEvent.patch)0
-rw-r--r--patches/server/0368-Entity-Jump-API.patch (renamed from patches/server/0363-Entity-Jump-API.patch)0
-rw-r--r--patches/server/0369-Add-option-to-nerf-pigmen-from-nether-portals.patch (renamed from patches/server/0364-Add-option-to-nerf-pigmen-from-nether-portals.patch)2
-rw-r--r--patches/server/0370-Make-the-GUI-graph-fancier.patch (renamed from patches/server/0365-Make-the-GUI-graph-fancier.patch)0
-rw-r--r--patches/server/0371-add-hand-to-BlockMultiPlaceEvent.patch (renamed from patches/server/0366-add-hand-to-BlockMultiPlaceEvent.patch)0
-rw-r--r--patches/server/0372-Validate-tripwire-hook-placement-before-update.patch (renamed from patches/server/0367-Validate-tripwire-hook-placement-before-update.patch)0
-rw-r--r--patches/server/0373-Add-option-to-allow-iron-golems-to-spawn-in-air.patch (renamed from patches/server/0368-Add-option-to-allow-iron-golems-to-spawn-in-air.patch)0
-rw-r--r--patches/server/0374-Configurable-chance-of-villager-zombie-infection.patch (renamed from patches/server/0369-Configurable-chance-of-villager-zombie-infection.patch)0
-rw-r--r--patches/server/0375-Optimise-Chunk-getFluid.patch (renamed from patches/server/0370-Optimise-Chunk-getFluid.patch)2
-rw-r--r--patches/server/0376-Set-spigots-verbose-world-setting-to-false-by-def.patch (renamed from patches/server/0371-Set-spigots-verbose-world-setting-to-false-by-def.patch)0
-rw-r--r--patches/server/0377-Add-tick-times-API-and-mspt-command.patch (renamed from patches/server/0372-Add-tick-times-API-and-mspt-command.patch)0
-rw-r--r--patches/server/0378-Expose-MinecraftServer-isRunning.patch (renamed from patches/server/0373-Expose-MinecraftServer-isRunning.patch)2
-rw-r--r--patches/server/0379-Add-Raw-Byte-ItemStack-Serialization.patch (renamed from patches/server/0374-Add-Raw-Byte-ItemStack-Serialization.patch)0
-rw-r--r--patches/server/0380-Pillager-patrol-spawn-settings-and-per-player-option.patch (renamed from patches/server/0375-Pillager-patrol-spawn-settings-and-per-player-option.patch)4
-rw-r--r--patches/server/0381-Remote-Connections-shouldn-t-hold-up-shutdown.patch (renamed from patches/server/0376-Remote-Connections-shouldn-t-hold-up-shutdown.patch)0
-rw-r--r--patches/server/0382-Do-not-allow-bees-to-load-chunks-for-beehives.patch (renamed from patches/server/0377-Do-not-allow-bees-to-load-chunks-for-beehives.patch)0
-rw-r--r--patches/server/0383-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch (renamed from patches/server/0378-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch)10
-rw-r--r--patches/server/0384-Don-t-tick-dead-players.patch (renamed from patches/server/0379-Don-t-tick-dead-players.patch)4
-rw-r--r--patches/server/0385-Dead-Player-s-shouldn-t-be-able-to-move.patch (renamed from patches/server/0380-Dead-Player-s-shouldn-t-be-able-to-move.patch)0
-rw-r--r--patches/server/0386-Optimize-Collision-to-not-load-chunks.patch (renamed from patches/server/0381-Optimize-Collision-to-not-load-chunks.patch)6
-rw-r--r--patches/server/0387-Don-t-move-existing-players-to-world-spawn.patch (renamed from patches/server/0382-Don-t-move-existing-players-to-world-spawn.patch)10
-rw-r--r--patches/server/0388-Optimize-GoalSelector-Goal.Flag-Set-operations.patch (renamed from patches/server/0383-Optimize-GoalSelector-Goal.Flag-Set-operations.patch)0
-rw-r--r--patches/server/0389-Improved-Watchdog-Support.patch (renamed from patches/server/0384-Improved-Watchdog-Support.patch)12
-rw-r--r--patches/server/0390-Optimize-Pathfinding.patch (renamed from patches/server/0385-Optimize-Pathfinding.patch)0
-rw-r--r--patches/server/0391-Reduce-Either-Optional-allocation.patch (renamed from patches/server/0386-Reduce-Either-Optional-allocation.patch)0
-rw-r--r--patches/server/0392-Reduce-memory-footprint-of-NBTTagCompound.patch (renamed from patches/server/0387-Reduce-memory-footprint-of-NBTTagCompound.patch)0
-rw-r--r--patches/server/0393-Prevent-opening-inventories-when-frozen.patch (renamed from patches/server/0388-Prevent-opening-inventories-when-frozen.patch)6
-rw-r--r--patches/server/0394-Optimise-ArraySetSorted-removeIf.patch (renamed from patches/server/0389-Optimise-ArraySetSorted-removeIf.patch)2
-rw-r--r--patches/server/0395-Don-t-run-entity-collision-code-if-not-needed.patch (renamed from patches/server/0390-Don-t-run-entity-collision-code-if-not-needed.patch)0
-rw-r--r--patches/server/0396-Implement-Player-Client-Options-API.patch (renamed from patches/server/0391-Implement-Player-Client-Options-API.patch)6
-rw-r--r--patches/server/0397-Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch (renamed from patches/server/0392-Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch)4
-rw-r--r--patches/server/0398-Fix-Chunk-Post-Processing-deadlock-risk.patch (renamed from patches/server/0393-Fix-Chunk-Post-Processing-deadlock-risk.patch)10
-rw-r--r--patches/server/0399-Fix-Longstanding-Broken-behavior-of-PlayerJoinEvent.patch (renamed from patches/server/0394-Fix-Longstanding-Broken-behavior-of-PlayerJoinEvent.patch)20
-rw-r--r--patches/server/0400-Load-Chunks-for-Login-Asynchronously.patch (renamed from patches/server/0395-Load-Chunks-for-Login-Asynchronously.patch)87
-rw-r--r--patches/server/0401-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch (renamed from patches/server/0396-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch)2
-rw-r--r--patches/server/0402-Add-PlayerAttackEntityCooldownResetEvent.patch (renamed from patches/server/0397-Add-PlayerAttackEntityCooldownResetEvent.patch)0
-rw-r--r--patches/server/0403-Don-t-fire-BlockFade-on-worldgen-threads.patch (renamed from patches/server/0398-Don-t-fire-BlockFade-on-worldgen-threads.patch)0
-rw-r--r--patches/server/0404-Add-phantom-creative-and-insomniac-controls.patch (renamed from patches/server/0399-Add-phantom-creative-and-insomniac-controls.patch)0
-rw-r--r--patches/server/0405-Fix-numerous-item-duplication-issues-and-teleport-is.patch (renamed from patches/server/0400-Fix-numerous-item-duplication-issues-and-teleport-is.patch)2
-rw-r--r--patches/server/0406-Villager-Restocks-API.patch (renamed from patches/server/0401-Villager-Restocks-API.patch)0
-rw-r--r--patches/server/0407-Validate-PickItem-Packet-and-kick-for-invalid.patch (renamed from patches/server/0402-Validate-PickItem-Packet-and-kick-for-invalid.patch)0
-rw-r--r--patches/server/0408-Expose-game-version.patch (renamed from patches/server/0403-Expose-game-version.patch)2
-rw-r--r--patches/server/0409-Optimize-Voxel-Shape-Merging.patch (renamed from patches/server/0404-Optimize-Voxel-Shape-Merging.patch)0
-rw-r--r--patches/server/0410-Set-cap-on-JDK-per-thread-native-byte-buffer-cache.patch (renamed from patches/server/0405-Set-cap-on-JDK-per-thread-native-byte-buffer-cache.patch)0
-rw-r--r--patches/server/0411-misc-debugging-dumps.patch (renamed from patches/server/0406-misc-debugging-dumps.patch)4
-rw-r--r--patches/server/0412-Prevent-teleporting-dead-entities.patch (renamed from patches/server/0407-Prevent-teleporting-dead-entities.patch)0
-rw-r--r--patches/server/0413-Deobfuscate-stacktraces-in-log-messages-crash-report.patch (renamed from patches/server/0408-Deobfuscate-stacktraces-in-log-messages-crash-report.patch)0
-rw-r--r--patches/server/0414-Implement-Mob-Goal-API.patch (renamed from patches/server/0409-Implement-Mob-Goal-API.patch)2
-rw-r--r--patches/server/0415-Add-villager-reputation-API.patch (renamed from patches/server/0410-Add-villager-reputation-API.patch)0
-rw-r--r--patches/server/0416-Option-for-maximum-exp-value-when-merging-orbs.patch (renamed from patches/server/0411-Option-for-maximum-exp-value-when-merging-orbs.patch)0
-rw-r--r--patches/server/0417-ExperienceOrbMergeEvent.patch (renamed from patches/server/0412-ExperienceOrbMergeEvent.patch)0
-rw-r--r--patches/server/0418-Fix-PotionEffect-ignores-icon-flag.patch (renamed from patches/server/0413-Fix-PotionEffect-ignores-icon-flag.patch)0
-rw-r--r--patches/server/0419-Optimize-brigadier-child-sorting-performance.patch (renamed from patches/server/0414-Optimize-brigadier-child-sorting-performance.patch)0
-rw-r--r--patches/server/0420-Potential-bed-API.patch (renamed from patches/server/0415-Potential-bed-API.patch)0
-rw-r--r--patches/server/0421-Wait-for-Async-Tasks-during-shutdown.patch (renamed from patches/server/0416-Wait-for-Async-Tasks-during-shutdown.patch)4
-rw-r--r--patches/server/0422-Ensure-EntityRaider-respects-game-and-entity-rules-f.patch (renamed from patches/server/0417-Ensure-EntityRaider-respects-game-and-entity-rules-f.patch)0
-rw-r--r--patches/server/0423-Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch (renamed from patches/server/0418-Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch)0
-rw-r--r--patches/server/0424-Reduce-MutableInt-allocations-from-light-engine.patch (renamed from patches/server/0419-Reduce-MutableInt-allocations-from-light-engine.patch)0
-rw-r--r--patches/server/0425-Reduce-allocation-of-Vec3D-by-entity-tracker.patch (renamed from patches/server/0420-Reduce-allocation-of-Vec3D-by-entity-tracker.patch)4
-rw-r--r--patches/server/0426-Ensure-safe-gateway-teleport.patch (renamed from patches/server/0421-Ensure-safe-gateway-teleport.patch)0
-rw-r--r--patches/server/0427-Add-option-for-console-having-all-permissions.patch (renamed from patches/server/0422-Add-option-for-console-having-all-permissions.patch)0
-rw-r--r--patches/server/0428-Optimize-anyPlayerCloseEnoughForSpawning-to-use-dist.patch (renamed from patches/server/0423-Optimize-anyPlayerCloseEnoughForSpawning-to-use-dist.patch)94
-rw-r--r--patches/server/0429-Use-distance-map-to-optimise-entity-tracker.patch (renamed from patches/server/0424-Use-distance-map-to-optimise-entity-tracker.patch)22
-rw-r--r--patches/server/0430-Optimize-ServerLevels-chunk-level-checking-methods.patch (renamed from patches/server/0425-Optimize-ServerLevels-chunk-level-checking-methods.patch)8
-rw-r--r--patches/server/0431-Fix-villager-trading-demand-MC-163962.patch (renamed from patches/server/0427-Fix-villager-trading-demand-MC-163962.patch)0
-rw-r--r--patches/server/0432-Maps-shouldn-t-load-chunks.patch (renamed from patches/server/0428-Maps-shouldn-t-load-chunks.patch)0
-rw-r--r--patches/server/0433-Use-seed-based-lookup-for-Treasure-Maps-Fixes-lag-fr.patch (renamed from patches/server/0429-Use-seed-based-lookup-for-Treasure-Maps-Fixes-lag-fr.patch)0
-rw-r--r--patches/server/0434-Fix-CraftScheduler-runTaskTimerAsynchronously-Plugin.patch (renamed from patches/server/0430-Fix-CraftScheduler-runTaskTimerAsynchronously-Plugin.patch)0
-rw-r--r--patches/server/0435-Fix-piston-physics-inconsistency-MC-188840.patch (renamed from patches/server/0431-Fix-piston-physics-inconsistency-MC-188840.patch)0
-rw-r--r--patches/server/0436-Fix-sand-duping.patch (renamed from patches/server/0432-Fix-sand-duping.patch)0
-rw-r--r--patches/server/0437-Fix-missing-chunks-due-to-integer-overflow.patch (renamed from patches/server/0433-Fix-missing-chunks-due-to-integer-overflow.patch)0
-rw-r--r--patches/server/0438-Prevent-position-desync-in-playerconnection-causing-.patch (renamed from patches/server/0434-Prevent-position-desync-in-playerconnection-causing-.patch)0
-rw-r--r--patches/server/0439-Inventory-getHolder-method-without-block-snapshot.patch (renamed from patches/server/0435-Inventory-getHolder-method-without-block-snapshot.patch)0
-rw-r--r--patches/server/0440-Improve-Arrow-API.patch (renamed from patches/server/0436-Improve-Arrow-API.patch)0
-rw-r--r--patches/server/0441-Add-and-implement-PlayerRecipeBookClickEvent.patch (renamed from patches/server/0437-Add-and-implement-PlayerRecipeBookClickEvent.patch)0
-rw-r--r--patches/server/0442-Hide-sync-chunk-writes-behind-flag.patch (renamed from patches/server/0438-Hide-sync-chunk-writes-behind-flag.patch)0
-rw-r--r--patches/server/0443-Add-permission-for-command-blocks.patch (renamed from patches/server/0439-Add-permission-for-command-blocks.patch)0
-rw-r--r--patches/server/0444-Ensure-Entity-AABB-s-are-never-invalid.patch (renamed from patches/server/0440-Ensure-Entity-AABB-s-are-never-invalid.patch)2
-rw-r--r--patches/server/0445-Fix-Per-World-Difficulty-Remembering-Difficulty.patch (renamed from patches/server/0441-Fix-Per-World-Difficulty-Remembering-Difficulty.patch)4
-rw-r--r--patches/server/0446-Paper-dumpitem-command.patch (renamed from patches/server/0442-Paper-dumpitem-command.patch)0
-rw-r--r--patches/server/0447-Don-t-allow-null-UUID-s-for-chat.patch (renamed from patches/server/0443-Don-t-allow-null-UUID-s-for-chat.patch)0
-rw-r--r--patches/server/0448-Improve-Legacy-Component-serialization-size.patch (renamed from patches/server/0444-Improve-Legacy-Component-serialization-size.patch)0
-rw-r--r--patches/server/0449-Optimize-Bit-Operations-by-inlining.patch (renamed from patches/server/0445-Optimize-Bit-Operations-by-inlining.patch)0
-rw-r--r--patches/server/0450-Add-Plugin-Tickets-to-API-Chunk-Methods.patch (renamed from patches/server/0446-Add-Plugin-Tickets-to-API-Chunk-Methods.patch)30
-rw-r--r--patches/server/0451-incremental-chunk-and-player-saving.patch (renamed from patches/server/0447-incremental-chunk-and-player-saving.patch)57
-rw-r--r--patches/server/0452-Stop-copy-on-write-operations-for-updating-light-dat.patch (renamed from patches/server/0448-Stop-copy-on-write-operations-for-updating-light-dat.patch)0
-rw-r--r--patches/server/0453-Support-old-UUID-format-for-NBT.patch (renamed from patches/server/0449-Support-old-UUID-format-for-NBT.patch)0
-rw-r--r--patches/server/0454-Clean-up-duplicated-GameProfile-Properties.patch (renamed from patches/server/0450-Clean-up-duplicated-GameProfile-Properties.patch)0
-rw-r--r--patches/server/0455-Convert-legacy-attributes-in-Item-Meta.patch (renamed from patches/server/0451-Convert-legacy-attributes-in-Item-Meta.patch)0
-rw-r--r--patches/server/0456-Remove-some-streams-from-structures.patch (renamed from patches/server/0452-Remove-some-streams-from-structures.patch)0
-rw-r--r--patches/server/0457-Remove-streams-from-classes-related-villager-gossip.patch (renamed from patches/server/0453-Remove-streams-from-classes-related-villager-gossip.patch)0
-rw-r--r--patches/server/0458-Support-components-in-ItemMeta.patch (renamed from patches/server/0454-Support-components-in-ItemMeta.patch)0
-rw-r--r--patches/server/0459-Improve-EntityTargetLivingEntityEvent-for-1.16-mobs.patch (renamed from patches/server/0455-Improve-EntityTargetLivingEntityEvent-for-1.16-mobs.patch)0
-rw-r--r--patches/server/0460-Add-entity-liquid-API.patch (renamed from patches/server/0456-Add-entity-liquid-API.patch)2
-rw-r--r--patches/server/0461-Update-itemstack-legacy-name-and-lore.patch (renamed from patches/server/0457-Update-itemstack-legacy-name-and-lore.patch)0
-rw-r--r--patches/server/0462-Spawn-player-in-correct-world-on-login.patch (renamed from patches/server/0458-Spawn-player-in-correct-world-on-login.patch)4
-rw-r--r--patches/server/0463-Add-PrepareResultEvent.patch (renamed from patches/server/0459-Add-PrepareResultEvent.patch)0
-rw-r--r--patches/server/0464-Don-t-check-chunk-for-portal-on-world-gen-entity-add.patch (renamed from patches/server/0460-Don-t-check-chunk-for-portal-on-world-gen-entity-add.patch)0
-rw-r--r--patches/server/0465-Optimize-NetworkManager-Exception-Handling.patch (renamed from patches/server/0462-Optimize-NetworkManager-Exception-Handling.patch)0
-rw-r--r--patches/server/0466-Optimize-the-advancement-data-player-iteration-to-be.patch (renamed from patches/server/0463-Optimize-the-advancement-data-player-iteration-to-be.patch)0
-rw-r--r--patches/server/0467-Fix-arrows-never-despawning-MC-125757.patch (renamed from patches/server/0464-Fix-arrows-never-despawning-MC-125757.patch)0
-rw-r--r--patches/server/0468-Thread-Safe-Vanilla-Command-permission-checking.patch (renamed from patches/server/0465-Thread-Safe-Vanilla-Command-permission-checking.patch)0
-rw-r--r--patches/server/0469-Fix-SPIGOT-5989.patch (renamed from patches/server/0466-Fix-SPIGOT-5989.patch)10
-rw-r--r--patches/server/0470-Fix-SPIGOT-5824-Bukkit-world-container-is-not-used.patch (renamed from patches/server/0467-Fix-SPIGOT-5824-Bukkit-world-container-is-not-used.patch)0
-rw-r--r--patches/server/0471-Fix-SPIGOT-5885-Unable-to-disable-advancements.patch (renamed from patches/server/0468-Fix-SPIGOT-5885-Unable-to-disable-advancements.patch)0
-rw-r--r--patches/server/0472-Fix-AdvancementDataPlayer-leak-due-from-quitting-ear.patch (renamed from patches/server/0469-Fix-AdvancementDataPlayer-leak-due-from-quitting-ear.patch)0
-rw-r--r--patches/server/0473-Add-missing-strikeLighting-call-to-World-spigot-stri.patch (renamed from patches/server/0470-Add-missing-strikeLighting-call-to-World-spigot-stri.patch)4
-rw-r--r--patches/server/0474-Fix-some-rails-connecting-improperly.patch (renamed from patches/server/0471-Fix-some-rails-connecting-improperly.patch)0
-rw-r--r--patches/server/0475-Fix-regex-mistake-in-CB-NBT-int-deserialization.patch (renamed from patches/server/0472-Fix-regex-mistake-in-CB-NBT-int-deserialization.patch)0
-rw-r--r--patches/server/0476-Do-not-let-the-server-load-chunks-from-newer-version.patch (renamed from patches/server/0473-Do-not-let-the-server-load-chunks-from-newer-version.patch)0
-rw-r--r--patches/server/0477-Brand-support.patch (renamed from patches/server/0474-Brand-support.patch)4
-rw-r--r--patches/server/0478-Add-setMaxPlayers-API.patch (renamed from patches/server/0475-Add-setMaxPlayers-API.patch)4
-rw-r--r--patches/server/0479-Add-playPickupItemAnimation-to-LivingEntity.patch (renamed from patches/server/0476-Add-playPickupItemAnimation-to-LivingEntity.patch)0
-rw-r--r--patches/server/0480-Don-t-require-FACING-data.patch (renamed from patches/server/0477-Don-t-require-FACING-data.patch)0
-rw-r--r--patches/server/0481-Fix-SpawnChangeEvent-not-firing-for-all-use-cases.patch (renamed from patches/server/0478-Fix-SpawnChangeEvent-not-firing-for-all-use-cases.patch)8
-rw-r--r--patches/server/0482-Add-moon-phase-API.patch (renamed from patches/server/0479-Add-moon-phase-API.patch)0
-rw-r--r--patches/server/0483-Improve-Chunk-Status-Transition-Speed.patch (renamed from patches/server/0480-Improve-Chunk-Status-Transition-Speed.patch)10
-rw-r--r--patches/server/0484-Prevent-headless-pistons-from-being-created.patch (renamed from patches/server/0481-Prevent-headless-pistons-from-being-created.patch)0
-rw-r--r--patches/server/0485-Add-BellRingEvent.patch (renamed from patches/server/0482-Add-BellRingEvent.patch)0
-rw-r--r--patches/server/0486-Add-zombie-targets-turtle-egg-config.patch (renamed from patches/server/0483-Add-zombie-targets-turtle-egg-config.patch)0
-rw-r--r--patches/server/0487-Buffer-joins-to-world.patch (renamed from patches/server/0484-Buffer-joins-to-world.patch)0
-rw-r--r--patches/server/0488-Eigencraft-redstone-implementation.patch (renamed from patches/server/0485-Eigencraft-redstone-implementation.patch)0
-rw-r--r--patches/server/0489-Fix-hex-colors-not-working-in-some-kick-messages.patch (renamed from patches/server/0486-Fix-hex-colors-not-working-in-some-kick-messages.patch)0
-rw-r--r--patches/server/0490-PortalCreateEvent-needs-to-know-its-entity.patch (renamed from patches/server/0487-PortalCreateEvent-needs-to-know-its-entity.patch)0
-rw-r--r--patches/server/0491-Fix-CraftTeam-null-check.patch (renamed from patches/server/0488-Fix-CraftTeam-null-check.patch)0
-rw-r--r--patches/server/0492-Add-more-Evoker-API.patch (renamed from patches/server/0489-Add-more-Evoker-API.patch)0
-rw-r--r--patches/server/0493-Add-methods-to-get-translation-keys.patch (renamed from patches/server/0490-Add-methods-to-get-translation-keys.patch)0
-rw-r--r--patches/server/0494-Create-HoverEvent-from-ItemStack-Entity.patch (renamed from patches/server/0491-Create-HoverEvent-from-ItemStack-Entity.patch)0
-rw-r--r--patches/server/0495-Cache-block-data-strings.patch (renamed from patches/server/0492-Cache-block-data-strings.patch)0
-rw-r--r--patches/server/0496-Fix-Entity-Teleportation-and-cancel-velocity-if-tele.patch (renamed from patches/server/0493-Fix-Entity-Teleportation-and-cancel-velocity-if-tele.patch)4
-rw-r--r--patches/server/0497-Add-additional-open-container-api-to-HumanEntity.patch (renamed from patches/server/0494-Add-additional-open-container-api-to-HumanEntity.patch)0
-rw-r--r--patches/server/0498-Cache-DataFixerUpper-Rewrite-Rules-on-demand.patch (renamed from patches/server/0495-Cache-DataFixerUpper-Rewrite-Rules-on-demand.patch)0
-rw-r--r--patches/server/0499-Extend-block-drop-capture-to-capture-all-items-added.patch (renamed from patches/server/0496-Extend-block-drop-capture-to-capture-all-items-added.patch)4
-rw-r--r--patches/server/0500-Don-t-mark-dirty-in-invalid-locations-SPIGOT-6086.patch (renamed from patches/server/0497-Don-t-mark-dirty-in-invalid-locations-SPIGOT-6086.patch)4
-rw-r--r--patches/server/0501-Expose-the-Entity-Counter-to-allow-plugins-to-use-va.patch (renamed from patches/server/0498-Expose-the-Entity-Counter-to-allow-plugins-to-use-va.patch)0
-rw-r--r--patches/server/0502-Lazily-track-plugin-scoreboards-by-default.patch (renamed from patches/server/0499-Lazily-track-plugin-scoreboards-by-default.patch)0
-rw-r--r--patches/server/0503-Entity-isTicking.patch (renamed from patches/server/0500-Entity-isTicking.patch)2
-rw-r--r--patches/server/0504-Fix-deop-kicking-non-whitelisted-player-when-white-l.patch (renamed from patches/server/0501-Fix-deop-kicking-non-whitelisted-player-when-white-l.patch)0
-rw-r--r--patches/server/0505-Fix-Concurrency-issue-in-ShufflingList.patch (renamed from patches/server/0502-Fix-Concurrency-issue-in-ShufflingList.patch)0
-rw-r--r--patches/server/0506-Reset-Ender-Crystals-on-Dragon-Spawn.patch (renamed from patches/server/0503-Reset-Ender-Crystals-on-Dragon-Spawn.patch)0
-rw-r--r--patches/server/0507-Fix-for-large-move-vectors-crashing-server.patch (renamed from patches/server/0504-Fix-for-large-move-vectors-crashing-server.patch)0
-rw-r--r--patches/server/0508-Optimise-getType-calls.patch (renamed from patches/server/0505-Optimise-getType-calls.patch)0
-rw-r--r--patches/server/0509-Villager-resetOffers.patch (renamed from patches/server/0506-Villager-resetOffers.patch)0
-rw-r--r--patches/server/0510-Improve-inlinig-for-some-hot-IBlockData-methods.patch (renamed from patches/server/0507-Improve-inlinig-for-some-hot-IBlockData-methods.patch)0
-rw-r--r--patches/server/0511-Retain-block-place-order-when-capturing-blockstates.patch (renamed from patches/server/0508-Retain-block-place-order-when-capturing-blockstates.patch)0
-rw-r--r--patches/server/0512-Reduce-blockpos-allocation-from-pathfinding.patch (renamed from patches/server/0509-Reduce-blockpos-allocation-from-pathfinding.patch)0
-rw-r--r--patches/server/0513-Fix-item-locations-dropped-from-campfires.patch (renamed from patches/server/0510-Fix-item-locations-dropped-from-campfires.patch)0
-rw-r--r--patches/server/0514-Player-elytra-boost-API.patch (renamed from patches/server/0511-Player-elytra-boost-API.patch)2
-rw-r--r--patches/server/0515-Fixed-TileEntityBell-memory-leak.patch (renamed from patches/server/0512-Fixed-TileEntityBell-memory-leak.patch)0
-rw-r--r--patches/server/0516-Avoid-error-bubbling-up-when-item-stack-is-empty-in-.patch (renamed from patches/server/0513-Avoid-error-bubbling-up-when-item-stack-is-empty-in-.patch)0
-rw-r--r--patches/server/0517-Add-getOfflinePlayerIfCached-String.patch (renamed from patches/server/0514-Add-getOfflinePlayerIfCached-String.patch)2
-rw-r--r--patches/server/0518-Add-ignore-discounts-API.patch (renamed from patches/server/0515-Add-ignore-discounts-API.patch)0
-rw-r--r--patches/server/0519-Toggle-for-removing-existing-dragon.patch (renamed from patches/server/0516-Toggle-for-removing-existing-dragon.patch)0
-rw-r--r--patches/server/0520-Fix-client-lag-on-advancement-loading.patch (renamed from patches/server/0517-Fix-client-lag-on-advancement-loading.patch)0
-rw-r--r--patches/server/0521-Item-no-age-no-player-pickup.patch (renamed from patches/server/0518-Item-no-age-no-player-pickup.patch)0
-rw-r--r--patches/server/0522-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch (renamed from patches/server/0519-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch)0
-rw-r--r--patches/server/0523-Beacon-API-custom-effect-ranges.patch (renamed from patches/server/0520-Beacon-API-custom-effect-ranges.patch)0
-rw-r--r--patches/server/0524-Add-API-for-quit-reason.patch (renamed from patches/server/0521-Add-API-for-quit-reason.patch)4
-rw-r--r--patches/server/0525-Add-Wandering-Trader-spawn-rate-config-options.patch (renamed from patches/server/0522-Add-Wandering-Trader-spawn-rate-config-options.patch)0
-rw-r--r--patches/server/0526-Expose-world-spawn-angle.patch (renamed from patches/server/0523-Expose-world-spawn-angle.patch)4
-rw-r--r--patches/server/0527-Add-Destroy-Speed-API.patch (renamed from patches/server/0524-Add-Destroy-Speed-API.patch)0
-rw-r--r--patches/server/0528-Fix-Player-spawnParticle-x-y-z-precision-loss.patch (renamed from patches/server/0525-Fix-Player-spawnParticle-x-y-z-precision-loss.patch)4
-rw-r--r--patches/server/0529-Add-LivingEntity-clearActiveItem.patch (renamed from patches/server/0526-Add-LivingEntity-clearActiveItem.patch)0
-rw-r--r--patches/server/0530-Add-PlayerItemCooldownEvent.patch (renamed from patches/server/0527-Add-PlayerItemCooldownEvent.patch)0
-rw-r--r--patches/server/0531-Significantly-improve-performance-of-the-end-generat.patch (renamed from patches/server/0528-Significantly-improve-performance-of-the-end-generat.patch)0
-rw-r--r--patches/server/0532-More-lightning-API.patch (renamed from patches/server/0529-More-lightning-API.patch)0
-rw-r--r--patches/server/0533-Climbing-should-not-bypass-cramming-gamerule.patch (renamed from patches/server/0530-Climbing-should-not-bypass-cramming-gamerule.patch)0
-rw-r--r--patches/server/0534-Added-missing-default-perms-for-commands.patch (renamed from patches/server/0531-Added-missing-default-perms-for-commands.patch)0
-rw-r--r--patches/server/0535-Add-PlayerShearBlockEvent.patch (renamed from patches/server/0532-Add-PlayerShearBlockEvent.patch)0
-rw-r--r--patches/server/0536-Fix-curing-zombie-villager-discount-exploit.patch (renamed from patches/server/0533-Fix-curing-zombie-villager-discount-exploit.patch)0
-rw-r--r--patches/server/0537-Limit-recipe-packets.patch (renamed from patches/server/0534-Limit-recipe-packets.patch)0
-rw-r--r--patches/server/0538-Fix-CraftSound-backwards-compatibility.patch (renamed from patches/server/0535-Fix-CraftSound-backwards-compatibility.patch)0
-rw-r--r--patches/server/0539-Player-Chunk-Load-Unload-Events.patch (renamed from patches/server/0536-Player-Chunk-Load-Unload-Events.patch)0
-rw-r--r--patches/server/0540-Optimize-Dynamic-get-Missing-Keys.patch (renamed from patches/server/0537-Optimize-Dynamic-get-Missing-Keys.patch)0
-rw-r--r--patches/server/0541-Expose-LivingEntity-hurt-direction.patch (renamed from patches/server/0538-Expose-LivingEntity-hurt-direction.patch)0
-rw-r--r--patches/server/0542-Add-OBSTRUCTED-reason-to-BedEnterResult.patch (renamed from patches/server/0539-Add-OBSTRUCTED-reason-to-BedEnterResult.patch)0
-rw-r--r--patches/server/0543-Do-not-crash-from-invalid-ingredient-lists-in-Villag.patch (renamed from patches/server/0540-Do-not-crash-from-invalid-ingredient-lists-in-Villag.patch)0
-rw-r--r--patches/server/0544-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch (renamed from patches/server/0541-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch)0
-rw-r--r--patches/server/0545-Implement-TargetHitEvent.patch (renamed from patches/server/0542-Implement-TargetHitEvent.patch)0
-rw-r--r--patches/server/0546-MC-4-Fix-item-position-desync.patch (renamed from patches/server/0543-MC-4-Fix-item-position-desync.patch)0
-rw-r--r--patches/server/0547-Additional-Block-Material-API-s.patch (renamed from patches/server/0544-Additional-Block-Material-API-s.patch)0
-rw-r--r--patches/server/0548-Fix-harming-potion-dupe.patch (renamed from patches/server/0545-Fix-harming-potion-dupe.patch)0
-rw-r--r--patches/server/0549-Implement-API-to-get-Material-from-Boats-and-Minecar.patch (renamed from patches/server/0546-Implement-API-to-get-Material-from-Boats-and-Minecar.patch)0
-rw-r--r--patches/server/0550-Cache-burn-durations.patch (renamed from patches/server/0547-Cache-burn-durations.patch)0
-rw-r--r--patches/server/0551-Allow-disabling-mob-spawner-spawn-egg-transformation.patch (renamed from patches/server/0548-Allow-disabling-mob-spawner-spawn-egg-transformation.patch)0
-rw-r--r--patches/server/0552-Fix-Not-a-string-Map-Conversion-spam.patch (renamed from patches/server/0549-Fix-Not-a-string-Map-Conversion-spam.patch)0
-rw-r--r--patches/server/0553-Implement-PlayerFlowerPotManipulateEvent.patch (renamed from patches/server/0550-Implement-PlayerFlowerPotManipulateEvent.patch)0
-rw-r--r--patches/server/0554-Fix-interact-event-not-being-called-in-adventure.patch (renamed from patches/server/0551-Fix-interact-event-not-being-called-in-adventure.patch)0
-rw-r--r--patches/server/0555-Zombie-API-breaking-doors.patch (renamed from patches/server/0552-Zombie-API-breaking-doors.patch)0
-rw-r--r--patches/server/0556-Fix-nerfed-slime-when-splitting.patch (renamed from patches/server/0553-Fix-nerfed-slime-when-splitting.patch)0
-rw-r--r--patches/server/0557-Add-EntityLoadCrossbowEvent.patch (renamed from patches/server/0554-Add-EntityLoadCrossbowEvent.patch)0
-rw-r--r--patches/server/0558-Guardian-beam-workaround.patch (renamed from patches/server/0555-Guardian-beam-workaround.patch)0
-rw-r--r--patches/server/0559-Added-WorldGameRuleChangeEvent.patch (renamed from patches/server/0556-Added-WorldGameRuleChangeEvent.patch)6
-rw-r--r--patches/server/0560-Added-ServerResourcesReloadedEvent.patch (renamed from patches/server/0557-Added-ServerResourcesReloadedEvent.patch)0
-rw-r--r--patches/server/0561-Added-world-settings-for-mobs-picking-up-loot.patch (renamed from patches/server/0558-Added-world-settings-for-mobs-picking-up-loot.patch)0
-rw-r--r--patches/server/0562-Implemented-BlockFailedDispenseEvent.patch (renamed from patches/server/0559-Implemented-BlockFailedDispenseEvent.patch)0
-rw-r--r--patches/server/0563-Added-PlayerLecternPageChangeEvent.patch (renamed from patches/server/0560-Added-PlayerLecternPageChangeEvent.patch)0
-rw-r--r--patches/server/0564-Added-PlayerLoomPatternSelectEvent.patch (renamed from patches/server/0561-Added-PlayerLoomPatternSelectEvent.patch)0
-rw-r--r--patches/server/0565-Configurable-door-breaking-difficulty.patch (renamed from patches/server/0562-Configurable-door-breaking-difficulty.patch)0
-rw-r--r--patches/server/0566-Empty-commands-shall-not-be-dispatched.patch (renamed from patches/server/0563-Empty-commands-shall-not-be-dispatched.patch)2
-rw-r--r--patches/server/0567-Implement-API-to-expose-exact-interaction-point.patch (renamed from patches/server/0564-Implement-API-to-expose-exact-interaction-point.patch)0
-rw-r--r--patches/server/0568-Remove-stale-POIs.patch (renamed from patches/server/0565-Remove-stale-POIs.patch)4
-rw-r--r--patches/server/0569-Fix-villager-boat-exploit.patch (renamed from patches/server/0566-Fix-villager-boat-exploit.patch)4
-rw-r--r--patches/server/0570-Add-sendOpLevel-API.patch (renamed from patches/server/0567-Add-sendOpLevel-API.patch)8
-rw-r--r--patches/server/0571-Add-PaperRegistry.patch (renamed from patches/server/0568-Add-PaperRegistry.patch)0
-rw-r--r--patches/server/0572-Add-StructuresLocateEvent.patch (renamed from patches/server/0569-Add-StructuresLocateEvent.patch)0
-rw-r--r--patches/server/0573-Collision-option-for-requiring-a-player-participant.patch (renamed from patches/server/0570-Collision-option-for-requiring-a-player-participant.patch)0
-rw-r--r--patches/server/0574-Remove-ProjectileHitEvent-call-when-fireballs-dead.patch (renamed from patches/server/0571-Remove-ProjectileHitEvent-call-when-fireballs-dead.patch)0
-rw-r--r--patches/server/0575-Return-chat-component-with-empty-text-instead-of-thr.patch (renamed from patches/server/0572-Return-chat-component-with-empty-text-instead-of-thr.patch)0
-rw-r--r--patches/server/0576-Make-schedule-command-per-world.patch (renamed from patches/server/0573-Make-schedule-command-per-world.patch)0
-rw-r--r--patches/server/0577-Configurable-max-leash-distance.patch (renamed from patches/server/0574-Configurable-max-leash-distance.patch)0
-rw-r--r--patches/server/0578-Implement-BlockPreDispenseEvent.patch (renamed from patches/server/0575-Implement-BlockPreDispenseEvent.patch)0
-rw-r--r--patches/server/0579-Added-firing-of-PlayerChangeBeaconEffectEvent.patch (renamed from patches/server/0576-Added-firing-of-PlayerChangeBeaconEffectEvent.patch)0
-rw-r--r--patches/server/0580-Add-toggle-for-always-placing-the-dragon-egg.patch (renamed from patches/server/0577-Add-toggle-for-always-placing-the-dragon-egg.patch)0
-rw-r--r--patches/server/0581-Added-PlayerStonecutterRecipeSelectEvent.patch (renamed from patches/server/0578-Added-PlayerStonecutterRecipeSelectEvent.patch)0
-rw-r--r--patches/server/0582-Add-dropLeash-variable-to-EntityUnleashEvent.patch (renamed from patches/server/0579-Add-dropLeash-variable-to-EntityUnleashEvent.patch)0
-rw-r--r--patches/server/0583-Reset-shield-blocking-on-dimension-change.patch (renamed from patches/server/0580-Reset-shield-blocking-on-dimension-change.patch)0
-rw-r--r--patches/server/0584-add-DragonEggFormEvent.patch (renamed from patches/server/0581-add-DragonEggFormEvent.patch)0
-rw-r--r--patches/server/0585-EntityMoveEvent.patch (renamed from patches/server/0582-EntityMoveEvent.patch)2
-rw-r--r--patches/server/0586-added-option-to-disable-pathfinding-updates-on-block.patch (renamed from patches/server/0583-added-option-to-disable-pathfinding-updates-on-block.patch)6
-rw-r--r--patches/server/0587-Inline-shift-direction-fields.patch (renamed from patches/server/0584-Inline-shift-direction-fields.patch)0
-rw-r--r--patches/server/0588-Allow-adding-items-to-BlockDropItemEvent.patch (renamed from patches/server/0585-Allow-adding-items-to-BlockDropItemEvent.patch)0
-rw-r--r--patches/server/0589-Add-getMainThreadExecutor-to-BukkitScheduler.patch (renamed from patches/server/0586-Add-getMainThreadExecutor-to-BukkitScheduler.patch)0
-rw-r--r--patches/server/0590-living-entity-allow-attribute-registration.patch (renamed from patches/server/0587-living-entity-allow-attribute-registration.patch)0
-rw-r--r--patches/server/0591-fix-dead-slime-setSize-invincibility.patch (renamed from patches/server/0588-fix-dead-slime-setSize-invincibility.patch)0
-rw-r--r--patches/server/0592-Merchant-getRecipes-should-return-an-immutable-list.patch (renamed from patches/server/0589-Merchant-getRecipes-should-return-an-immutable-list.patch)0
-rw-r--r--patches/server/0593-Add-support-for-hex-color-codes-in-console.patch (renamed from patches/server/0590-Add-support-for-hex-color-codes-in-console.patch)0
-rw-r--r--patches/server/0594-Expose-Tracked-Players.patch (renamed from patches/server/0591-Expose-Tracked-Players.patch)2
-rw-r--r--patches/server/0595-Remove-streams-from-SensorNearest.patch (renamed from patches/server/0592-Remove-streams-from-SensorNearest.patch)0
-rw-r--r--patches/server/0596-Throw-proper-exception-on-empty-JsonList-file.patch (renamed from patches/server/0593-Throw-proper-exception-on-empty-JsonList-file.patch)0
-rw-r--r--patches/server/0597-Improve-ServerGUI.patch (renamed from patches/server/0594-Improve-ServerGUI.patch)0
-rw-r--r--patches/server/0598-stop-firing-pressure-plate-EntityInteractEvent-for-i.patch (renamed from patches/server/0595-stop-firing-pressure-plate-EntityInteractEvent-for-i.patch)0
-rw-r--r--patches/server/0599-fix-converting-txt-to-json-file.patch (renamed from patches/server/0596-fix-converting-txt-to-json-file.patch)2
-rw-r--r--patches/server/0600-Add-worldborder-events.patch (renamed from patches/server/0597-Add-worldborder-events.patch)0
-rw-r--r--patches/server/0601-added-PlayerNameEntityEvent.patch (renamed from patches/server/0598-added-PlayerNameEntityEvent.patch)0
-rw-r--r--patches/server/0602-Prevent-grindstones-from-overstacking-items.patch (renamed from patches/server/0599-Prevent-grindstones-from-overstacking-items.patch)0
-rw-r--r--patches/server/0603-Add-recipe-to-cook-events.patch (renamed from patches/server/0600-Add-recipe-to-cook-events.patch)0
-rw-r--r--patches/server/0604-Add-Block-isValidTool.patch (renamed from patches/server/0601-Add-Block-isValidTool.patch)0
-rw-r--r--patches/server/0605-Allow-using-signs-inside-spawn-protection.patch (renamed from patches/server/0602-Allow-using-signs-inside-spawn-protection.patch)0
-rw-r--r--patches/server/0606-Expand-world-key-API.patch (renamed from patches/server/0603-Expand-world-key-API.patch)2
-rw-r--r--patches/server/0607-Add-fast-alternative-constructor-for-Rotations.patch (renamed from patches/server/0604-Add-fast-alternative-constructor-for-Rotations.patch)0
-rw-r--r--patches/server/0608-Item-Rarity-API.patch (renamed from patches/server/0605-Item-Rarity-API.patch)0
-rw-r--r--patches/server/0609-Only-set-despawnTimer-for-Wandering-Traders-spawned-.patch (renamed from patches/server/0606-Only-set-despawnTimer-for-Wandering-Traders-spawned-.patch)0
-rw-r--r--patches/server/0610-copy-TESign-isEditable-from-snapshots.patch (renamed from patches/server/0607-copy-TESign-isEditable-from-snapshots.patch)0
-rw-r--r--patches/server/0611-Drop-carried-item-when-player-has-disconnected.patch (renamed from patches/server/0608-Drop-carried-item-when-player-has-disconnected.patch)4
-rw-r--r--patches/server/0612-forced-whitelist-use-configurable-kick-message.patch (renamed from patches/server/0609-forced-whitelist-use-configurable-kick-message.patch)0
-rw-r--r--patches/server/0613-Don-t-ignore-result-of-PlayerEditBookEvent.patch (renamed from patches/server/0610-Don-t-ignore-result-of-PlayerEditBookEvent.patch)0
-rw-r--r--patches/server/0614-Entity-load-save-limit-per-chunk.patch (renamed from patches/server/0611-Entity-load-save-limit-per-chunk.patch)0
-rw-r--r--patches/server/0615-Expose-protocol-version.patch (renamed from patches/server/0612-Expose-protocol-version.patch)0
-rw-r--r--patches/server/0616-Enhance-console-tab-completions-for-brigadier-comman.patch (renamed from patches/server/0613-Enhance-console-tab-completions-for-brigadier-comman.patch)0
-rw-r--r--patches/server/0617-Fix-PlayerItemConsumeEvent-cancelling-properly.patch (renamed from patches/server/0614-Fix-PlayerItemConsumeEvent-cancelling-properly.patch)0
-rw-r--r--patches/server/0618-Add-bypass-host-check.patch (renamed from patches/server/0615-Add-bypass-host-check.patch)0
-rw-r--r--patches/server/0619-Set-area-affect-cloud-rotation.patch (renamed from patches/server/0616-Set-area-affect-cloud-rotation.patch)0
-rw-r--r--patches/server/0620-add-isDeeplySleeping-to-HumanEntity.patch (renamed from patches/server/0617-add-isDeeplySleeping-to-HumanEntity.patch)0
-rw-r--r--patches/server/0621-add-consumeFuel-to-FurnaceBurnEvent.patch (renamed from patches/server/0618-add-consumeFuel-to-FurnaceBurnEvent.patch)0
-rw-r--r--patches/server/0622-add-get-set-drop-chance-to-EntityEquipment.patch (renamed from patches/server/0619-add-get-set-drop-chance-to-EntityEquipment.patch)0
-rw-r--r--patches/server/0623-fix-PigZombieAngerEvent-cancellation.patch (renamed from patches/server/0620-fix-PigZombieAngerEvent-cancellation.patch)0
-rw-r--r--patches/server/0624-Fix-checkReach-check-for-Shulker-boxes.patch (renamed from patches/server/0621-Fix-checkReach-check-for-Shulker-boxes.patch)0
-rw-r--r--patches/server/0625-fix-PlayerItemHeldEvent-firing-twice.patch (renamed from patches/server/0622-fix-PlayerItemHeldEvent-firing-twice.patch)0
-rw-r--r--patches/server/0626-Added-PlayerDeepSleepEvent.patch (renamed from patches/server/0623-Added-PlayerDeepSleepEvent.patch)0
-rw-r--r--patches/server/0627-More-World-API.patch (renamed from patches/server/0624-More-World-API.patch)4
-rw-r--r--patches/server/0628-Added-PlayerBedFailEnterEvent.patch (renamed from patches/server/0625-Added-PlayerBedFailEnterEvent.patch)0
-rw-r--r--patches/server/0629-Implement-methods-to-convert-between-Component-and-B.patch (renamed from patches/server/0626-Implement-methods-to-convert-between-Component-and-B.patch)0
-rw-r--r--patches/server/0630-Fix-anchor-respawn-acting-as-a-bed-respawn-from-the-.patch (renamed from patches/server/0627-Fix-anchor-respawn-acting-as-a-bed-respawn-from-the-.patch)8
-rw-r--r--patches/server/0631-Introduce-beacon-activation-deactivation-events.patch (renamed from patches/server/0628-Introduce-beacon-activation-deactivation-events.patch)0
-rw-r--r--patches/server/0632-add-RespawnFlags-to-PlayerRespawnEvent.patch (renamed from patches/server/0629-add-RespawnFlags-to-PlayerRespawnEvent.patch)6
-rw-r--r--patches/server/0633-Add-Channel-initialization-listeners.patch (renamed from patches/server/0630-Add-Channel-initialization-listeners.patch)0
-rw-r--r--patches/server/0634-Send-empty-commands-if-tab-completion-is-disabled.patch (renamed from patches/server/0631-Send-empty-commands-if-tab-completion-is-disabled.patch)2
-rw-r--r--patches/server/0635-Add-more-WanderingTrader-API.patch (renamed from patches/server/0632-Add-more-WanderingTrader-API.patch)0
-rw-r--r--patches/server/0636-Add-EntityBlockStorage-clearEntities.patch (renamed from patches/server/0633-Add-EntityBlockStorage-clearEntities.patch)0
-rw-r--r--patches/server/0637-Add-Adventure-message-to-PlayerAdvancementDoneEvent.patch (renamed from patches/server/0634-Add-Adventure-message-to-PlayerAdvancementDoneEvent.patch)0
-rw-r--r--patches/server/0638-Add-raw-address-to-AsyncPlayerPreLoginEvent.patch (renamed from patches/server/0635-Add-raw-address-to-AsyncPlayerPreLoginEvent.patch)0
-rw-r--r--patches/server/0639-Inventory-close.patch (renamed from patches/server/0636-Inventory-close.patch)0
-rw-r--r--patches/server/0640-call-PortalCreateEvent-players-and-end-platform.patch (renamed from patches/server/0637-call-PortalCreateEvent-players-and-end-platform.patch)0
-rw-r--r--patches/server/0641-Add-a-should-burn-in-sunlight-API-for-Phantoms-and-S.patch (renamed from patches/server/0638-Add-a-should-burn-in-sunlight-API-for-Phantoms-and-S.patch)0
-rw-r--r--patches/server/0642-Fix-CraftPotionBrewer-cache.patch (renamed from patches/server/0639-Fix-CraftPotionBrewer-cache.patch)0
-rw-r--r--patches/server/0643-Add-basic-Datapack-API.patch (renamed from patches/server/0640-Add-basic-Datapack-API.patch)2
-rw-r--r--patches/server/0644-Add-environment-variable-to-disable-server-gui.patch (renamed from patches/server/0641-Add-environment-variable-to-disable-server-gui.patch)0
-rw-r--r--patches/server/0645-additions-to-PlayerGameModeChangeEvent.patch (renamed from patches/server/0642-additions-to-PlayerGameModeChangeEvent.patch)4
-rw-r--r--patches/server/0646-ItemStack-repair-check-API.patch (renamed from patches/server/0643-ItemStack-repair-check-API.patch)0
-rw-r--r--patches/server/0647-More-Enchantment-API.patch (renamed from patches/server/0644-More-Enchantment-API.patch)0
-rw-r--r--patches/server/0648-Move-range-check-for-block-placing-up.patch (renamed from patches/server/0645-Move-range-check-for-block-placing-up.patch)0
-rw-r--r--patches/server/0649-Fix-and-optimise-world-force-upgrading.patch (renamed from patches/server/0646-Fix-and-optimise-world-force-upgrading.patch)6
-rw-r--r--patches/server/0650-Add-Mob-lookAt-API.patch (renamed from patches/server/0647-Add-Mob-lookAt-API.patch)0
-rw-r--r--patches/server/0651-Add-Unix-domain-socket-support.patch (renamed from patches/server/0648-Add-Unix-domain-socket-support.patch)0
-rw-r--r--patches/server/0652-Add-EntityInsideBlockEvent.patch (renamed from patches/server/0649-Add-EntityInsideBlockEvent.patch)0
-rw-r--r--patches/server/0653-Attributes-API-for-item-defaults.patch (renamed from patches/server/0650-Attributes-API-for-item-defaults.patch)0
-rw-r--r--patches/server/0654-Add-cause-to-Weather-ThunderChangeEvents.patch (renamed from patches/server/0651-Add-cause-to-Weather-ThunderChangeEvents.patch)14
-rw-r--r--patches/server/0655-More-Lidded-Block-API.patch (renamed from patches/server/0652-More-Lidded-Block-API.patch)0
-rw-r--r--patches/server/0656-Limit-item-frame-cursors-on-maps.patch (renamed from patches/server/0653-Limit-item-frame-cursors-on-maps.patch)0
-rw-r--r--patches/server/0657-Add-PlayerKickEvent-causes.patch (renamed from patches/server/0654-Add-PlayerKickEvent-causes.patch)8
-rw-r--r--patches/server/0658-Add-PufferFishStateChangeEvent.patch (renamed from patches/server/0655-Add-PufferFishStateChangeEvent.patch)0
-rw-r--r--patches/server/0659-Fix-PlayerBucketEmptyEvent-result-itemstack.patch (renamed from patches/server/0656-Fix-PlayerBucketEmptyEvent-result-itemstack.patch)0
-rw-r--r--patches/server/0660-Synchronize-PalettedContainer-instead-of-ThreadingDe.patch (renamed from patches/server/0657-Synchronize-PalettedContainer-instead-of-ThreadingDe.patch)0
-rw-r--r--patches/server/0661-Add-option-to-fix-items-merging-through-walls.patch (renamed from patches/server/0658-Add-option-to-fix-items-merging-through-walls.patch)0
-rw-r--r--patches/server/0662-Add-BellRevealRaiderEvent.patch (renamed from patches/server/0659-Add-BellRevealRaiderEvent.patch)0
-rw-r--r--patches/server/0663-Fix-invulnerable-end-crystals.patch (renamed from patches/server/0660-Fix-invulnerable-end-crystals.patch)0
-rw-r--r--patches/server/0664-Add-ElderGuardianAppearanceEvent.patch (renamed from patches/server/0661-Add-ElderGuardianAppearanceEvent.patch)0
-rw-r--r--patches/server/0665-Fix-dangerous-end-portal-logic.patch (renamed from patches/server/0662-Fix-dangerous-end-portal-logic.patch)0
-rw-r--r--patches/server/0666-Optimize-Biome-Mob-Lookups-for-Mob-Spawning.patch (renamed from patches/server/0663-Optimize-Biome-Mob-Lookups-for-Mob-Spawning.patch)0
-rw-r--r--patches/server/0667-Make-item-validations-configurable.patch (renamed from patches/server/0664-Make-item-validations-configurable.patch)0
-rw-r--r--patches/server/0668-Line-Of-Sight-Changes.patch (renamed from patches/server/0665-Line-Of-Sight-Changes.patch)0
-rw-r--r--patches/server/0669-add-per-world-spawn-limits.patch (renamed from patches/server/0666-add-per-world-spawn-limits.patch)4
-rw-r--r--patches/server/0670-Fix-PotionSplashEvent-for-water-splash-potions.patch (renamed from patches/server/0667-Fix-PotionSplashEvent-for-water-splash-potions.patch)0
-rw-r--r--patches/server/0671-Add-more-LimitedRegion-API.patch (renamed from patches/server/0668-Add-more-LimitedRegion-API.patch)0
-rw-r--r--patches/server/0672-Fix-PlayerDropItemEvent-using-wrong-item.patch (renamed from patches/server/0669-Fix-PlayerDropItemEvent-using-wrong-item.patch)0
-rw-r--r--patches/server/0673-Missing-Entity-Behavior-API.patch (renamed from patches/server/0670-Missing-Entity-Behavior-API.patch)0
-rw-r--r--patches/server/0674-Ensure-disconnect-for-book-edit-is-called-on-main.patch (renamed from patches/server/0671-Ensure-disconnect-for-book-edit-is-called-on-main.patch)0
-rw-r--r--patches/server/0675-Fix-return-value-of-Block-applyBoneMeal-always-being.patch (renamed from patches/server/0672-Fix-return-value-of-Block-applyBoneMeal-always-being.patch)0
-rw-r--r--patches/server/0676-Use-getChunkIfLoadedImmediately-in-places.patch (renamed from patches/server/0673-Use-getChunkIfLoadedImmediately-in-places.patch)4
-rw-r--r--patches/server/0677-Fix-commands-from-signs-not-firing-command-events.patch (renamed from patches/server/0674-Fix-commands-from-signs-not-firing-command-events.patch)0
-rw-r--r--patches/server/0678-Adds-PlayerArmSwingEvent.patch (renamed from patches/server/0675-Adds-PlayerArmSwingEvent.patch)0
-rw-r--r--patches/server/0679-Fixes-kick-event-leave-message-not-being-sent.patch (renamed from patches/server/0676-Fixes-kick-event-leave-message-not-being-sent.patch)6
-rw-r--r--patches/server/0680-Add-config-for-mobs-immune-to-default-effects.patch (renamed from patches/server/0677-Add-config-for-mobs-immune-to-default-effects.patch)0
-rw-r--r--patches/server/0681-Fix-incorrect-message-for-outdated-client.patch (renamed from patches/server/0678-Fix-incorrect-message-for-outdated-client.patch)0
-rw-r--r--patches/server/0682-Don-t-apply-cramming-damage-to-players.patch (renamed from patches/server/0679-Don-t-apply-cramming-damage-to-players.patch)0
-rw-r--r--patches/server/0683-Rate-options-and-timings-for-sensors-and-behaviors.patch (renamed from patches/server/0680-Rate-options-and-timings-for-sensors-and-behaviors.patch)0
-rw-r--r--patches/server/0684-Add-a-bunch-of-missing-forceDrop-toggles.patch (renamed from patches/server/0681-Add-a-bunch-of-missing-forceDrop-toggles.patch)0
-rw-r--r--patches/server/0685-Stinger-API.patch (renamed from patches/server/0682-Stinger-API.patch)0
-rw-r--r--patches/server/0686-Fix-incosistency-issue-with-empty-map-items-in-CB.patch (renamed from patches/server/0683-Fix-incosistency-issue-with-empty-map-items-in-CB.patch)0
-rw-r--r--patches/server/0687-Add-System.out-err-catcher.patch (renamed from patches/server/0684-Add-System.out-err-catcher.patch)2
-rw-r--r--patches/server/0688-Fix-test-not-bootstrapping.patch (renamed from patches/server/0685-Fix-test-not-bootstrapping.patch)0
-rw-r--r--patches/server/0689-Rewrite-LogEvents-to-contain-the-source-jars-in-stac.patch (renamed from patches/server/0686-Rewrite-LogEvents-to-contain-the-source-jars-in-stac.patch)0
-rw-r--r--patches/server/0690-Improve-boat-collision-performance.patch (renamed from patches/server/0687-Improve-boat-collision-performance.patch)0
-rw-r--r--patches/server/0691-Prevent-AFK-kick-while-watching-end-credits.patch (renamed from patches/server/0688-Prevent-AFK-kick-while-watching-end-credits.patch)0
-rw-r--r--patches/server/0692-Allow-skipping-writing-of-comments-to-server.propert.patch (renamed from patches/server/0689-Allow-skipping-writing-of-comments-to-server.propert.patch)0
-rw-r--r--patches/server/0693-Add-PlayerSetSpawnEvent.patch (renamed from patches/server/0690-Add-PlayerSetSpawnEvent.patch)8
-rw-r--r--patches/server/0694-Make-hoppers-respect-inventory-max-stack-size.patch (renamed from patches/server/0691-Make-hoppers-respect-inventory-max-stack-size.patch)0
-rw-r--r--patches/server/0695-Optimize-entity-tracker-passenger-checks.patch (renamed from patches/server/0692-Optimize-entity-tracker-passenger-checks.patch)0
-rw-r--r--patches/server/0696-Config-option-for-Piglins-guarding-chests.patch (renamed from patches/server/0693-Config-option-for-Piglins-guarding-chests.patch)0
-rw-r--r--patches/server/0697-Added-EntityDamageItemEvent.patch (renamed from patches/server/0694-Added-EntityDamageItemEvent.patch)0
-rw-r--r--patches/server/0698-Optimize-indirect-passenger-iteration.patch (renamed from patches/server/0695-Optimize-indirect-passenger-iteration.patch)0
-rw-r--r--patches/server/0699-Fix-block-drops-position-losing-precision-millions-o.patch (renamed from patches/server/0696-Fix-block-drops-position-losing-precision-millions-o.patch)0
-rw-r--r--patches/server/0700-Configurable-item-frame-map-cursor-update-interval.patch (renamed from patches/server/0697-Configurable-item-frame-map-cursor-update-interval.patch)0
-rw-r--r--patches/server/0701-Make-EntityUnleashEvent-cancellable.patch (renamed from patches/server/0698-Make-EntityUnleashEvent-cancellable.patch)0
-rw-r--r--patches/server/0702-Clear-bucket-NBT-after-dispense.patch (renamed from patches/server/0699-Clear-bucket-NBT-after-dispense.patch)0
-rw-r--r--patches/server/0703-Change-EnderEye-target-without-changing-other-things.patch (renamed from patches/server/0700-Change-EnderEye-target-without-changing-other-things.patch)0
-rw-r--r--patches/server/0704-Add-BlockBreakBlockEvent.patch (renamed from patches/server/0701-Add-BlockBreakBlockEvent.patch)0
-rw-r--r--patches/server/0705-Option-to-prevent-NBT-copy-in-smithing-recipes.patch (renamed from patches/server/0702-Option-to-prevent-NBT-copy-in-smithing-recipes.patch)0
-rw-r--r--patches/server/0706-More-CommandBlock-API.patch (renamed from patches/server/0703-More-CommandBlock-API.patch)0
-rw-r--r--patches/server/0707-Add-missing-team-sidebar-display-slots.patch (renamed from patches/server/0704-Add-missing-team-sidebar-display-slots.patch)0
-rw-r--r--patches/server/0708-Add-back-EntityPortalExitEvent.patch (renamed from patches/server/0705-Add-back-EntityPortalExitEvent.patch)0
-rw-r--r--patches/server/0709-Add-methods-to-find-targets-for-lightning-strikes.patch (renamed from patches/server/0706-Add-methods-to-find-targets-for-lightning-strikes.patch)10
-rw-r--r--patches/server/0710-Get-entity-default-attributes.patch (renamed from patches/server/0707-Get-entity-default-attributes.patch)0
-rw-r--r--patches/server/0711-Left-handed-API.patch (renamed from patches/server/0708-Left-handed-API.patch)0
-rw-r--r--patches/server/0712-Add-advancement-display-API.patch (renamed from patches/server/0709-Add-advancement-display-API.patch)0
-rw-r--r--patches/server/0713-Add-ItemFactory-getMonsterEgg-API.patch (renamed from patches/server/0710-Add-ItemFactory-getMonsterEgg-API.patch)0
-rw-r--r--patches/server/0714-Add-critical-damage-API.patch (renamed from patches/server/0711-Add-critical-damage-API.patch)0
-rw-r--r--patches/server/0715-Fix-issues-with-mob-conversion.patch (renamed from patches/server/0712-Fix-issues-with-mob-conversion.patch)0
-rw-r--r--patches/server/0716-Add-isCollidable-methods-to-various-places.patch (renamed from patches/server/0713-Add-isCollidable-methods-to-various-places.patch)0
-rw-r--r--patches/server/0717-Goat-ram-API.patch (renamed from patches/server/0714-Goat-ram-API.patch)0
-rw-r--r--patches/server/0718-Add-API-for-resetting-a-single-score.patch (renamed from patches/server/0715-Add-API-for-resetting-a-single-score.patch)0
-rw-r--r--patches/server/0719-Add-Raw-Byte-Entity-Serialization.patch (renamed from patches/server/0716-Add-Raw-Byte-Entity-Serialization.patch)2
-rw-r--r--patches/server/0720-Vanilla-command-permission-fixes.patch (renamed from patches/server/0717-Vanilla-command-permission-fixes.patch)2
-rw-r--r--patches/server/0721-Do-not-allow-the-server-to-unload-chunks-at-request-.patch (renamed from patches/server/0719-Do-not-allow-the-server-to-unload-chunks-at-request-.patch)4
-rw-r--r--patches/server/0722-Do-not-run-close-logic-for-inventories-on-chunk-unlo.patch (renamed from patches/server/0720-Do-not-run-close-logic-for-inventories-on-chunk-unlo.patch)4
-rw-r--r--patches/server/0723-Correctly-handle-recursion-for-chunkholder-updates.patch (renamed from patches/server/0721-Correctly-handle-recursion-for-chunkholder-updates.patch)6
-rw-r--r--patches/server/0724-Fix-GameProfileCache-concurrency.patch (renamed from patches/server/0722-Fix-GameProfileCache-concurrency.patch)0
-rw-r--r--patches/server/0725-Fix-chunks-refusing-to-unload-at-low-TPS.patch (renamed from patches/server/0723-Fix-chunks-refusing-to-unload-at-low-TPS.patch)4
-rw-r--r--patches/server/0726-Do-not-allow-ticket-level-changes-while-unloading-pl.patch (renamed from patches/server/0724-Do-not-allow-ticket-level-changes-while-unloading-pl.patch)22
-rw-r--r--patches/server/0727-Do-not-allow-ticket-level-changes-when-updating-chun.patch (renamed from patches/server/0725-Do-not-allow-ticket-level-changes-when-updating-chun.patch)6
-rw-r--r--patches/server/0728-Log-when-the-async-catcher-is-tripped.patch (renamed from patches/server/0726-Log-when-the-async-catcher-is-tripped.patch)0
-rw-r--r--patches/server/0729-Add-paper-mobcaps-and-paper-playermobcaps.patch (renamed from patches/server/0727-Add-paper-mobcaps-and-paper-playermobcaps.patch)6
-rw-r--r--patches/server/0730-Prevent-unload-calls-removing-tickets-for-sync-loads.patch (renamed from patches/server/0728-Prevent-unload-calls-removing-tickets-for-sync-loads.patch)8
-rw-r--r--patches/server/0731-Sanitize-ResourceLocation-error-logging.patch (renamed from patches/server/0729-Sanitize-ResourceLocation-error-logging.patch)0
-rw-r--r--patches/server/0732-Allow-controlled-flushing-for-network-manager.patch (renamed from patches/server/0730-Allow-controlled-flushing-for-network-manager.patch)0
-rw-r--r--patches/server/0733-Optimise-general-POI-access.patch (renamed from patches/server/0731-Optimise-general-POI-access.patch)0
-rw-r--r--patches/server/0734-Add-more-async-catchers.patch (renamed from patches/server/0732-Add-more-async-catchers.patch)4
-rw-r--r--patches/server/0735-Rewrite-entity-bounding-box-lookup-calls.patch (renamed from patches/server/0733-Rewrite-entity-bounding-box-lookup-calls.patch)14
-rw-r--r--patches/server/0736-Do-not-copy-visible-chunks.patch238
-rw-r--r--patches/server/0736-Optimise-chunk-tick-iteration.patch (renamed from patches/server/0734-Optimise-chunk-tick-iteration.patch)36
-rw-r--r--patches/server/0737-Execute-chunk-tasks-mid-tick.patch (renamed from patches/server/0735-Execute-chunk-tasks-mid-tick.patch)12
-rw-r--r--patches/server/0738-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch (renamed from patches/server/0737-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch)2
-rw-r--r--patches/server/0739-Custom-table-implementation-for-blockstate-state-loo.patch (renamed from patches/server/0738-Custom-table-implementation-for-blockstate-state-loo.patch)0
-rw-r--r--patches/server/0740-Detail-more-information-in-watchdog-dumps.patch (renamed from patches/server/0739-Detail-more-information-in-watchdog-dumps.patch)6
-rw-r--r--patches/server/0741-Manually-inline-methods-in-BlockPosition.patch (renamed from patches/server/0740-Manually-inline-methods-in-BlockPosition.patch)0
-rw-r--r--patches/server/0742-Distance-manager-tick-timings.patch (renamed from patches/server/0741-Distance-manager-tick-timings.patch)6
-rw-r--r--patches/server/0743-Name-craft-scheduler-threads-according-to-the-plugin.patch (renamed from patches/server/0742-Name-craft-scheduler-threads-according-to-the-plugin.patch)0
-rw-r--r--patches/server/0744-Make-sure-inlined-getChunkAt-has-inlined-logic-for-l.patch (renamed from patches/server/0743-Make-sure-inlined-getChunkAt-has-inlined-logic-for-l.patch)0
-rw-r--r--patches/server/0745-Add-packet-limiter-config.patch (renamed from patches/server/0744-Add-packet-limiter-config.patch)0
-rw-r--r--patches/server/0746-Use-correct-LevelStem-registry-when-loading-default-.patch (renamed from patches/server/0745-Use-correct-LevelStem-registry-when-loading-default-.patch)2
-rw-r--r--patches/server/0747-Don-t-read-neighbour-chunk-data-off-disk-when-conver.patch (renamed from patches/server/0746-Don-t-read-neighbour-chunk-data-off-disk-when-conver.patch)0
-rw-r--r--patches/server/0748-Consolidate-flush-calls-for-entity-tracker-packets.patch (renamed from patches/server/0747-Consolidate-flush-calls-for-entity-tracker-packets.patch)4
-rw-r--r--patches/server/0749-Don-t-lookup-fluid-state-when-raytracing.patch (renamed from patches/server/0748-Don-t-lookup-fluid-state-when-raytracing.patch)0
-rw-r--r--patches/server/0750-Time-scoreboard-search.patch (renamed from patches/server/0749-Time-scoreboard-search.patch)2
-rw-r--r--patches/server/0751-Send-full-pos-packets-for-hard-colliding-entities.patch (renamed from patches/server/0750-Send-full-pos-packets-for-hard-colliding-entities.patch)0
-rw-r--r--patches/server/0752-Do-not-run-raytrace-logic-for-AIR.patch (renamed from patches/server/0751-Do-not-run-raytrace-logic-for-AIR.patch)0
-rw-r--r--patches/server/0753-Oprimise-map-impl-for-tracked-players.patch (renamed from patches/server/0752-Oprimise-map-impl-for-tracked-players.patch)4
-rw-r--r--patches/server/0754-Optimise-BlockSoil-nearby-water-lookup.patch (renamed from patches/server/0753-Optimise-BlockSoil-nearby-water-lookup.patch)0
-rw-r--r--patches/server/0755-Allow-removal-addition-of-entities-to-entity-ticklis.patch (renamed from patches/server/0754-Allow-removal-addition-of-entities-to-entity-ticklis.patch)0
-rw-r--r--patches/server/0756-Optimise-random-block-ticking.patch (renamed from patches/server/0755-Optimise-random-block-ticking.patch)8
-rw-r--r--patches/server/0757-Optimise-non-flush-packet-sending.patch (renamed from patches/server/0756-Optimise-non-flush-packet-sending.patch)0
-rw-r--r--patches/server/0758-Optimise-nearby-player-lookups.patch (renamed from patches/server/0757-Optimise-nearby-player-lookups.patch)18
-rw-r--r--patches/server/0759-Optimise-WorldServer-notify.patch (renamed from patches/server/0758-Optimise-WorldServer-notify.patch)18
-rw-r--r--patches/server/0760-Remove-streams-for-villager-AI.patch (renamed from patches/server/0759-Remove-streams-for-villager-AI.patch)0
-rw-r--r--patches/server/0761-Rewrite-dataconverter-system.patch (renamed from patches/server/0760-Rewrite-dataconverter-system.patch)0
-rw-r--r--patches/server/0762-Use-Velocity-compression-and-cipher-natives.patch (renamed from patches/server/0761-Use-Velocity-compression-and-cipher-natives.patch)0
-rw-r--r--patches/server/0763-Reduce-worldgen-thread-worker-count-for-low-core-cou.patch (renamed from patches/server/0762-Reduce-worldgen-thread-worker-count-for-low-core-cou.patch)0
-rw-r--r--patches/server/0764-Do-not-process-entity-loads-in-CraftChunk-getEntitie.patch (renamed from patches/server/0763-Do-not-process-entity-loads-in-CraftChunk-getEntitie.patch)0
-rw-r--r--patches/server/0765-Async-catch-modifications-to-critical-entity-state.patch (renamed from patches/server/0764-Async-catch-modifications-to-critical-entity-state.patch)30
-rw-r--r--patches/server/0766-Fix-Bukkit-NamespacedKey-shenanigans.patch (renamed from patches/server/0765-Fix-Bukkit-NamespacedKey-shenanigans.patch)0
-rw-r--r--patches/server/0767-Fix-merchant-inventory-not-closing-on-entity-removal.patch (renamed from patches/server/0766-Fix-merchant-inventory-not-closing-on-entity-removal.patch)4
-rw-r--r--patches/server/0768-Check-requirement-before-suggesting-root-nodes.patch (renamed from patches/server/0767-Check-requirement-before-suggesting-root-nodes.patch)0
-rw-r--r--patches/server/0769-Don-t-respond-to-ServerboundCommandSuggestionPacket-.patch (renamed from patches/server/0768-Don-t-respond-to-ServerboundCommandSuggestionPacket-.patch)0
-rw-r--r--patches/server/0770-Fix-setPatternColor-on-tropical-fish-bucket-meta.patch (renamed from patches/server/0769-Fix-setPatternColor-on-tropical-fish-bucket-meta.patch)0
-rw-r--r--patches/server/0771-Ensure-valid-vehicle-status.patch (renamed from patches/server/0770-Ensure-valid-vehicle-status.patch)0
-rw-r--r--patches/server/0772-Prevent-softlocked-end-exit-portal-generation.patch (renamed from patches/server/0771-Prevent-softlocked-end-exit-portal-generation.patch)0
-rw-r--r--patches/server/0773-Fix-CocaoDecorator-causing-a-crash-when-trying-to-ge.patch (renamed from patches/server/0772-Fix-CocaoDecorator-causing-a-crash-when-trying-to-ge.patch)0
-rw-r--r--patches/server/0774-Don-t-log-debug-logging-being-disabled.patch (renamed from patches/server/0773-Don-t-log-debug-logging-being-disabled.patch)0
-rw-r--r--patches/server/0775-Do-not-overload-I-O-threads-with-chunk-data-while-fl.patch42
-rw-r--r--patches/server/0775-fix-various-menus-with-empty-level-accesses.patch (renamed from patches/server/0774-fix-various-menus-with-empty-level-accesses.patch)0
-rw-r--r--patches/server/0781-Add-config-option-for-logging-player-ip-addresses.patch4
-rw-r--r--patches/server/0797-Add-player-health-update-API.patch6
-rw-r--r--patches/server/0800-Highly-optimise-single-and-multi-AABB-VoxelShapes-an.patch4
-rw-r--r--patches/server/0802-Actually-unload-POI-data.patch50
-rw-r--r--patches/server/0806-Only-write-chunk-data-to-disk-if-it-serializes-witho.patch8
-rw-r--r--patches/server/0821-Validate-usernames.patch4
-rw-r--r--patches/server/0824-Expose-vanilla-BiomeProvider-from-WorldInfo.patch8
-rw-r--r--patches/server/0835-Freeze-Tick-Lock-API.patch4
-rw-r--r--patches/server/0841-Implement-regenerateChunk.patch4
-rw-r--r--patches/server/0854-Replace-player-chunk-loader-system.patch74
-rw-r--r--patches/server/0856-Force-close-world-loading-screen.patch4
-rw-r--r--patches/server/0857-Fix-falling-block-spawn-methods.patch6
-rw-r--r--patches/server/0860-Fix-save-problems-on-shutdown.patch4
-rw-r--r--patches/server/0880-Use-username-instead-of-display-name-in-PlayerList-g.patch4
-rw-r--r--patches/server/0882-Pass-ServerLevel-for-gamerule-callbacks.patch6
-rw-r--r--patches/server/0892-Don-t-tick-markers.patch4
-rw-r--r--patches/server/0901-Add-Alternate-Current-redstone-implementation.patch4
-rw-r--r--patches/server/0909-Prevent-empty-items-from-being-added-to-world.patch4
-rw-r--r--patches/server/0919-More-Teleport-API.patch17
-rw-r--r--patches/server/0923-Warn-on-plugins-accessing-faraway-chunks.patch18
-rw-r--r--patches/server/0936-Workaround-for-client-lag-spikes-MC-162253.patch6
792 files changed, 8789 insertions, 1792 deletions
diff --git a/patches/server/0006-ConcurrentUtil.patch b/patches/server/0006-ConcurrentUtil.patch
new file mode 100644
index 0000000000..065818eebe
--- /dev/null
+++ b/patches/server/0006-ConcurrentUtil.patch
@@ -0,0 +1,6864 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Spottedleaf <[email protected]>
+Date: Sun, 23 Jan 2022 22:58:11 -0800
+Subject: [PATCH] ConcurrentUtil
+
+
+diff --git a/src/main/java/ca/spottedleaf/concurrentutil/collection/MultiThreadedQueue.java b/src/main/java/ca/spottedleaf/concurrentutil/collection/MultiThreadedQueue.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..f4415f782b32fed25da98e44b172f717c4d46e34
+--- /dev/null
++++ b/src/main/java/ca/spottedleaf/concurrentutil/collection/MultiThreadedQueue.java
+@@ -0,0 +1,1402 @@
++package ca.spottedleaf.concurrentutil.collection;
++
++import ca.spottedleaf.concurrentutil.util.ConcurrentUtil;
++import ca.spottedleaf.concurrentutil.util.Validate;
++import java.lang.invoke.VarHandle;
++import java.util.ArrayList;
++import java.util.Collection;
++import java.util.Iterator;
++import java.util.List;
++import java.util.NoSuchElementException;
++import java.util.Queue;
++import java.util.Spliterator;
++import java.util.Spliterators;
++import java.util.function.Consumer;
++import java.util.function.IntFunction;
++import java.util.function.Predicate;
++
++/**
++ * MT-Safe linked first in first out ordered queue.
++ *
++ * This queue should out-perform {@link java.util.concurrent.ConcurrentLinkedQueue} in high-contention reads/writes, and is
++ * not any slower in lower contention reads/writes.
++ * <p>
++ * Note that this queue breaks the specification laid out by {@link Collection}, see {@link #preventAdds()} and {@link Collection#add(Object)}.
++ * </p>
++ * <p><b>
++ * This queue will only unlink linked nodes through the {@link #peek()} and {@link #poll()} methods, and this is only if
++ * they are at the head of the queue.
++ * </b></p>
++ * @param <E> Type of element in this queue.
++ */
++public class MultiThreadedQueue<E> implements Queue<E> {
++
++ protected volatile LinkedNode<E> head; /* Always non-null, high chance of being the actual head */
++
++ protected volatile LinkedNode<E> tail; /* Always non-null, high chance of being the actual tail */
++
++ /* Note that it is possible to reach head from tail. */
++
++ /* IMPL NOTE: Leave hashCode and equals to their defaults */
++
++ protected static final VarHandle HEAD_HANDLE = ConcurrentUtil.getVarHandle(MultiThreadedQueue.class, "head", LinkedNode.class);
++ protected static final VarHandle TAIL_HANDLE = ConcurrentUtil.getVarHandle(MultiThreadedQueue.class, "tail", LinkedNode.class);
++
++ /* head */
++
++ protected final void setHeadPlain(final LinkedNode<E> newHead) {
++ HEAD_HANDLE.set(this, newHead);
++ }
++
++ protected final void setHeadOpaque(final LinkedNode<E> newHead) {
++ HEAD_HANDLE.setOpaque(this, newHead);
++ }
++
++ @SuppressWarnings("unchecked")
++ protected final LinkedNode<E> getHeadPlain() {
++ return (LinkedNode<E>)HEAD_HANDLE.get(this);
++ }
++
++ @SuppressWarnings("unchecked")
++ protected final LinkedNode<E> getHeadOpaque() {
++ return (LinkedNode<E>)HEAD_HANDLE.getOpaque(this);
++ }
++
++ @SuppressWarnings("unchecked")
++ protected final LinkedNode<E> getHeadAcquire() {
++ return (LinkedNode<E>)HEAD_HANDLE.getAcquire(this);
++ }
++
++ /* tail */
++
++ protected final void setTailPlain(final LinkedNode<E> newTail) {
++ TAIL_HANDLE.set(this, newTail);
++ }
++
++ protected final void setTailOpaque(final LinkedNode<E> newTail) {
++ TAIL_HANDLE.setOpaque(this, newTail);
++ }
++
++ @SuppressWarnings("unchecked")
++ protected final LinkedNode<E> getTailPlain() {
++ return (LinkedNode<E>)TAIL_HANDLE.get(this);
++ }
++
++ @SuppressWarnings("unchecked")
++ protected final LinkedNode<E> getTailOpaque() {
++ return (LinkedNode<E>)TAIL_HANDLE.getOpaque(this);
++ }
++
++ /**
++ * Constructs a {@code MultiThreadedQueue}, initially empty.
++ * <p>
++ * The returned object may not be published without synchronization.
++ * </p>
++ */
++ public MultiThreadedQueue() {
++ final LinkedNode<E> value = new LinkedNode<>(null, null);
++ this.setHeadPlain(value);
++ this.setTailPlain(value);
++ }
++
++ /**
++ * Constructs a {@code MultiThreadedQueue}, initially containing all elements in the specified {@code collection}.
++ * <p>
++ * The returned object may not be published without synchronization.
++ * </p>
++ * @param collection The specified collection.
++ * @throws NullPointerException If {@code collection} is {@code null} or contains {@code null} elements.
++ */
++ public MultiThreadedQueue(final Iterable<? extends E> collection) {
++ final Iterator<? extends E> elements = collection.iterator();
++
++ if (!elements.hasNext()) {
++ final LinkedNode<E> value = new LinkedNode<>(null, null);
++ this.setHeadPlain(value);
++ this.setTailPlain(value);
++ return;
++ }
++
++ final LinkedNode<E> head = new LinkedNode<>(Validate.notNull(elements.next(), "Null element"), null);
++ LinkedNode<E> tail = head;
++
++ while (elements.hasNext()) {
++ final LinkedNode<E> next = new LinkedNode<>(Validate.notNull(elements.next(), "Null element"), null);
++ tail.setNextPlain(next);
++ tail = next;
++ }
++
++ this.setHeadPlain(head);
++ this.setTailPlain(tail);
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public E remove() throws NoSuchElementException {
++ final E ret = this.poll();
++
++ if (ret == null) {
++ throw new NoSuchElementException();
++ }
++
++ return ret;
++ }
++
++ /**
++ * {@inheritDoc}
++ * <p>
++ * Contrary to the specification of {@link Collection#add}, this method will fail to add the element to this queue
++ * and return {@code false} if this queue is add-blocked.
++ * </p>
++ */
++ @Override
++ public boolean add(final E element) {
++ return this.offer(element);
++ }
++
++ /**
++ * Adds the specified element to the tail of this queue. If this queue is currently add-locked, then the queue is
++ * released from that lock and this element is added. The unlock operation and addition of the specified
++ * element is atomic.
++ * @param element The specified element.
++ * @return {@code true} if this queue previously allowed additions
++ */
++ public boolean forceAdd(final E element) {
++ final LinkedNode<E> node = new LinkedNode<>(element, null);
++
++ return !this.forceAppendList(node, node);
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public E element() throws NoSuchElementException {
++ final E ret = this.peek();
++
++ if (ret == null) {
++ throw new NoSuchElementException();
++ }
++
++ return ret;
++ }
++
++ /**
++ * {@inheritDoc}
++ * <p>
++ * This method may also return {@code false} to indicate an element was not added if this queue is add-blocked.
++ * </p>
++ */
++ @Override
++ public boolean offer(final E element) {
++ Validate.notNull(element, "Null element");
++
++ final LinkedNode<E> node = new LinkedNode<>(element, null);
++
++ return this.appendList(node, node);
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public E peek() {
++ for (LinkedNode<E> head = this.getHeadOpaque(), curr = head;;) {
++ final LinkedNode<E> next = curr.getNextVolatile();
++ final E element = curr.getElementPlain(); /* Likely in sync */
++
++ if (element != null) {
++ if (this.getHeadOpaque() == head && curr != head) {
++ this.setHeadOpaque(curr);
++ }
++ return element;
++ }
++
++ if (next == null || curr == next) {
++ return null;
++ }
++ curr = next;
++ }
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public E poll() {
++ return this.removeHead();
++ }
++
++ /**
++ * Retrieves and removes the head of this queue if it matches the specified predicate. If this queue is empty
++ * or the head does not match the predicate, this function returns {@code null}.
++ * <p>
++ * The predicate may be invoked multiple or no times in this call.
++ * </p>
++ * @param predicate The specified predicate.
++ * @return The head if it matches the predicate, or {@code null} if it did not or this queue is empty.
++ */
++ public E pollIf(final Predicate<E> predicate) {
++ return this.removeHead(Validate.notNull(predicate, "Null predicate"));
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public void clear() {
++ //noinspection StatementWithEmptyBody
++ while (this.poll() != null);
++ }
++
++ /**
++ * Prevents elements from being added to this queue. Once this is called, any attempt to add to this queue will fail.
++ * <p>
++ * This function is MT-Safe.
++ * </p>
++ * @return {@code true} if the queue was modified to prevent additions, {@code false} if it already prevented additions.
++ */
++ public boolean preventAdds() {
++ final LinkedNode<E> deadEnd = new LinkedNode<>(null, null);
++ deadEnd.setNextPlain(deadEnd);
++
++ if (!this.appendList(deadEnd, deadEnd)) {
++ return false;
++ }
++
++ this.setTailPlain(deadEnd); /* (try to) Ensure tail is set for the following #allowAdds call */
++ return true;
++ }
++
++ /**
++ * Allows elements to be added to this queue once again. Note that this function has undefined behaviour if
++ * {@link #preventAdds()} is not called beforehand. The benefit of this function over {@link #tryAllowAdds()}
++ * is that this function might perform better.
++ * <p>
++ * This function is not MT-Safe.
++ * </p>
++ */
++ public void allowAdds() {
++ LinkedNode<E> tail = this.getTailPlain();
++
++ /* We need to find the tail given the cas on tail isn't atomic (nor volatile) in this.appendList */
++ /* Thus it is possible for an outdated tail to be set */
++ while (tail != (tail = tail.getNextPlain())) {}
++
++ tail.setNextVolatile(null);
++ }
++
++ /**
++ * Tries to allow elements to be added to this queue. Returns {@code true} if the queue was previous add-locked,
++ * {@code false} otherwise.
++ * <p>
++ * This function is MT-Safe, however it should not be used with {@link #allowAdds()}.
++ * </p>
++ * @return {@code true} if the queue was previously add-locked, {@code false} otherwise.
++ */
++ public boolean tryAllowAdds() {
++ LinkedNode<E> tail = this.getTailPlain();
++
++ for (int failures = 0;;) {
++ /* We need to find the tail given the cas on tail isn't atomic (nor volatile) in this.appendList */
++ /* Thus it is possible for an outdated tail to be set */
++ while (tail != (tail = tail.getNextAcquire())) {
++ if (tail == null) {
++ return false;
++ }
++ }
++
++ for (int i = 0; i < failures; ++i) {
++ ConcurrentUtil.backoff();
++ }
++
++ if (tail == (tail = tail.compareExchangeNextVolatile(tail, null))) {
++ return true;
++ }
++
++ if (tail == null) {
++ return false;
++ }
++ ++failures;
++ }
++ }
++
++ /**
++ * Atomically adds the specified element to this queue or allows additions to the queue. If additions
++ * are not allowed, the element is not added.
++ * <p>
++ * This function is MT-Safe.
++ * </p>
++ * @param element The specified element.
++ * @return {@code true} if the queue now allows additions, {@code false} if the element was added.
++ */
++ public boolean addOrAllowAdds(final E element) {
++ Validate.notNull(element, "Null element");
++ int failures = 0;
++
++ final LinkedNode<E> append = new LinkedNode<>(element, null);
++
++ for (LinkedNode<E> currTail = this.getTailOpaque(), curr = currTail;;) {
++ /* It has been experimentally shown that placing the read before the backoff results in significantly greater performance */
++ /* It is likely due to a cache miss caused by another write to the next field */
++ final LinkedNode<E> next = curr.getNextVolatile();
++
++ for (int i = 0; i < failures; ++i) {
++ ConcurrentUtil.backoff();
++ }
++
++ if (next == null) {
++ final LinkedNode<E> compared = curr.compareExchangeNextVolatile(null, append);
++
++ if (compared == null) {
++ /* Added */
++ /* Avoid CASing on tail more than we need to */
++ /* CAS to avoid setting an out-of-date tail */
++ if (this.getTailOpaque() == currTail) {
++ this.setTailOpaque(append);
++ }
++ return false; // we added
++ }
++
++ ++failures;
++ curr = compared;
++ continue;
++ } else if (next == curr) {
++ final LinkedNode<E> compared = curr.compareExchangeNextVolatile(curr, null);
++
++ if (compared == curr) {
++ return true; // we let additions through
++ }
++
++ ++failures;
++
++ if (compared != null) {
++ curr = compared;
++ }
++ continue;
++ }
++
++ if (curr == currTail) {
++ /* Tail is likely not up-to-date */
++ curr = next;
++ } else {
++ /* Try to update to tail */
++ if (currTail == (currTail = this.getTailOpaque())) {
++ curr = next;
++ } else {
++ curr = currTail;
++ }
++ }
++ }
++ }
++
++ /**
++ * Atomically removes the head from this queue if it exists, otherwise prevents additions to this queue if no
++ * head is removed.
++ * <p>
++ * This function is MT-Safe.
++ * </p>
++ * If the queue is already add-blocked and empty then no operation is performed.
++ * @return {@code null} if the queue is now add-blocked or was previously add-blocked, else returns
++ * an non-null value which was the previous head of queue.
++ */
++ public E pollOrBlockAdds() {
++ int failures = 0;
++ for (LinkedNode<E> head = this.getHeadOpaque(), curr = head;;) {
++ final E currentVal = curr.getElementVolatile();
++ final LinkedNode<E> next = curr.getNextOpaque();
++
++ if (next == curr) {
++ return null; /* Additions are already blocked */
++ }
++
++ for (int i = 0; i < failures; ++i) {
++ ConcurrentUtil.backoff();
++ }
++
++ if (currentVal != null) {
++ if (curr.getAndSetElementVolatile(null) == null) {
++ ++failures;
++ continue;
++ }
++
++ /* "CAS" to avoid setting an out-of-date head */
++ if (this.getHeadOpaque() == head) {
++ this.setHeadOpaque(next != null ? next : curr);
++ }
++
++ return currentVal;
++ }
++
++ if (next == null) {
++ /* Try to update stale head */
++ if (curr != head && this.getHeadOpaque() == head) {
++ this.setHeadOpaque(curr);
++ }
++
++ final LinkedNode<E> compared = curr.compareExchangeNextVolatile(null, curr);
++
++ if (compared != null) {
++ // failed to block additions
++ curr = compared;
++ ++failures;
++ continue;
++ }
++
++ return null; /* We blocked additions */
++ }
++
++ if (head == curr) {
++ /* head is likely not up-to-date */
++ curr = next;
++ } else {
++ /* Try to update to head */
++ if (head == (head = this.getHeadOpaque())) {
++ curr = next;
++ } else {
++ curr = head;
++ }
++ }
++ }
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public boolean remove(final Object object) {
++ Validate.notNull(object, "Null object to remove");
++
++ for (LinkedNode<E> curr = this.getHeadOpaque();;) {
++ final LinkedNode<E> next = curr.getNextVolatile();
++ final E element = curr.getElementPlain(); /* Likely in sync */
++
++ if (element != null) {
++ if ((element == object || element.equals(object)) && curr.getAndSetElementVolatile(null) == element) {
++ return true;
++ }
++ }
++
++ if (next == curr || next == null) {
++ break;
++ }
++ curr = next;
++ }
++
++ return false;
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public boolean removeIf(final Predicate<? super E> filter) {
++ Validate.notNull(filter, "Null filter");
++
++ boolean ret = false;
++
++ for (LinkedNode<E> curr = this.getHeadOpaque();;) {
++ final LinkedNode<E> next = curr.getNextVolatile();
++ final E element = curr.getElementPlain(); /* Likely in sync */
++
++ if (element != null) {
++ ret |= filter.test(element) && curr.getAndSetElementVolatile(null) == element;
++ }
++
++ if (next == null || next == curr) {
++ break;
++ }
++ curr = next;
++ }
++
++ return ret;
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public boolean removeAll(final Collection<?> collection) {
++ Validate.notNull(collection, "Null collection");
++
++ boolean ret = false;
++
++ /* Volatile is required to synchronize with the write to the first element */
++ for (LinkedNode<E> curr = this.getHeadOpaque();;) {
++ final LinkedNode<E> next = curr.getNextVolatile();
++ final E element = curr.getElementPlain(); /* Likely in sync */
++
++ if (element != null) {
++ ret |= collection.contains(element) && curr.getAndSetElementVolatile(null) == element;
++ }
++
++ if (next == null || next == curr) {
++ break;
++ }
++ curr = next;
++ }
++
++ return ret;
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public boolean retainAll(final Collection<?> collection) {
++ Validate.notNull(collection, "Null collection");
++
++ boolean ret = false;
++
++ for (LinkedNode<E> curr = this.getHeadOpaque();;) {
++ final LinkedNode<E> next = curr.getNextVolatile();
++ final E element = curr.getElementPlain(); /* Likely in sync */
++
++ if (element != null) {
++ ret |= !collection.contains(element) && curr.getAndSetElementVolatile(null) == element;
++ }
++
++ if (next == null || next == curr) {
++ break;
++ }
++ curr = next;
++ }
++
++ return ret;
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public Object[] toArray() {
++ final List<E> ret = new ArrayList<>();
++
++ for (LinkedNode<E> curr = this.getHeadOpaque();;) {
++ final LinkedNode<E> next = curr.getNextVolatile();
++ final E element = curr.getElementPlain(); /* Likely in sync */
++
++ if (element != null) {
++ ret.add(element);
++ }
++
++ if (next == null || next == curr) {
++ break;
++ }
++ curr = next;
++ }
++
++ return ret.toArray();
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public <T> T[] toArray(final T[] array) {
++ final List<T> ret = new ArrayList<>();
++
++ for (LinkedNode<E> curr = this.getHeadOpaque();;) {
++ final LinkedNode<E> next = curr.getNextVolatile();
++ final E element = curr.getElementPlain(); /* Likely in sync */
++
++ if (element != null) {
++ //noinspection unchecked
++ ret.add((T)element);
++ }
++
++ if (next == null || next == curr) {
++ break;
++ }
++ curr = next;
++ }
++
++ return ret.toArray(array);
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public <T> T[] toArray(final IntFunction<T[]> generator) {
++ Validate.notNull(generator, "Null generator");
++
++ final List<T> ret = new ArrayList<>();
++
++ for (LinkedNode<E> curr = this.getHeadOpaque();;) {
++ final LinkedNode<E> next = curr.getNextVolatile();
++ final E element = curr.getElementPlain(); /* Likely in sync */
++
++ if (element != null) {
++ //noinspection unchecked
++ ret.add((T)element);
++ }
++
++ if (next == null || next == curr) {
++ break;
++ }
++ curr = next;
++ }
++
++ return ret.toArray(generator);
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public String toString() {
++ final StringBuilder builder = new StringBuilder();
++
++ builder.append("MultiThreadedQueue: {elements: {");
++
++ int deadEntries = 0;
++ int totalEntries = 0;
++ int aliveEntries = 0;
++
++ boolean addLocked = false;
++
++ for (LinkedNode<E> curr = this.getHeadOpaque();; ++totalEntries) {
++ final LinkedNode<E> next = curr.getNextVolatile();
++ final E element = curr.getElementPlain(); /* Likely in sync */
++
++ if (element == null) {
++ ++deadEntries;
++ } else {
++ ++aliveEntries;
++ }
++
++ if (totalEntries != 0) {
++ builder.append(", ");
++ }
++
++ builder.append(totalEntries).append(": \"").append(element).append('"');
++
++ if (next == null) {
++ break;
++ }
++ if (curr == next) {
++ addLocked = true;
++ break;
++ }
++ curr = next;
++ }
++
++ builder.append("}, total_entries: \"").append(totalEntries).append("\", alive_entries: \"").append(aliveEntries)
++ .append("\", dead_entries:").append(deadEntries).append("\", add_locked: \"").append(addLocked)
++ .append("\"}");
++
++ return builder.toString();
++ }
++
++ /**
++ * Adds all elements from the specified collection to this queue. The addition is atomic.
++ * @param collection The specified collection.
++ * @return {@code true} if all elements were added successfully, or {@code false} if this queue is add-blocked, or
++ * {@code false} if the specified collection contains no elements.
++ */
++ @Override
++ public boolean addAll(final Collection<? extends E> collection) {
++ return this.addAll((Iterable<? extends E>)collection);
++ }
++
++ /**
++ * Adds all elements from the specified iterable object to this queue. The addition is atomic.
++ * @param iterable The specified iterable object.
++ * @return {@code true} if all elements were added successfully, or {@code false} if this queue is add-blocked, or
++ * {@code false} if the specified iterable contains no elements.
++ */
++ public boolean addAll(final Iterable<? extends E> iterable) {
++ Validate.notNull(iterable, "Null iterable");
++
++ final Iterator<? extends E> elements = iterable.iterator();
++ if (!elements.hasNext()) {
++ return false;
++ }
++
++ /* Build a list of nodes to append */
++ /* This is an much faster due to the fact that zero additional synchronization is performed */
++
++ final LinkedNode<E> head = new LinkedNode<>(Validate.notNull(elements.next(), "Null element"), null);
++ LinkedNode<E> tail = head;
++
++ while (elements.hasNext()) {
++ final LinkedNode<E> next = new LinkedNode<>(Validate.notNull(elements.next(), "Null element"), null);
++ tail.setNextPlain(next);
++ tail = next;
++ }
++
++ return this.appendList(head, tail);
++ }
++
++ /**
++ * Adds all of the elements from the specified array to this queue.
++ * @param items The specified array.
++ * @return {@code true} if all elements were added successfully, or {@code false} if this queue is add-blocked, or
++ * {@code false} if the specified array has a length of 0.
++ */
++ public boolean addAll(final E[] items) {
++ return this.addAll(items, 0, items.length);
++ }
++
++ /**
++ * Adds all of the elements from the specified array to this queue.
++ * @param items The specified array.
++ * @param off The offset in the array.
++ * @param len The number of items.
++ * @return {@code true} if all elements were added successfully, or {@code false} if this queue is add-blocked, or
++ * {@code false} if the specified array has a length of 0.
++ */
++ public boolean addAll(final E[] items, final int off, final int len) {
++ Validate.notNull(items, "Items may not be null");
++ Validate.arrayBounds(off, len, items.length, "Items array indices out of bounds");
++
++ if (len == 0) {
++ return false;
++ }
++
++ final LinkedNode<E> head = new LinkedNode<>(Validate.notNull(items[off], "Null element"), null);
++ LinkedNode<E> tail = head;
++
++ for (int i = 1; i < len; ++i) {
++ final LinkedNode<E> next = new LinkedNode<>(Validate.notNull(items[off + i], "Null element"), null);
++ tail.setNextPlain(next);
++ tail = next;
++ }
++
++ return this.appendList(head, tail);
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public boolean containsAll(final Collection<?> collection) {
++ Validate.notNull(collection, "Null collection");
++
++ for (final Object element : collection) {
++ if (!this.contains(element)) {
++ return false;
++ }
++ }
++ return false;
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public Iterator<E> iterator() {
++ return new LinkedIterator<>(this.getHeadOpaque());
++ }
++
++ /**
++ * {@inheritDoc}
++ * <p>
++ * Note that this function is computed non-atomically and in O(n) time. The value returned may not be representative of
++ * the queue in its current state.
++ * </p>
++ */
++ @Override
++ public int size() {
++ int size = 0;
++
++ /* Volatile is required to synchronize with the write to the first element */
++ for (LinkedNode<E> curr = this.getHeadOpaque();;) {
++ final LinkedNode<E> next = curr.getNextVolatile();
++ final E element = curr.getElementPlain(); /* Likely in sync */
++
++ if (element != null) {
++ ++size;
++ }
++
++ if (next == null || next == curr) {
++ break;
++ }
++ curr = next;
++ }
++
++ return size;
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public boolean isEmpty() {
++ return this.peek() == null;
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public boolean contains(final Object object) {
++ Validate.notNull(object, "Null object");
++
++ for (LinkedNode<E> curr = this.getHeadOpaque();;) {
++ final LinkedNode<E> next = curr.getNextVolatile();
++ final E element = curr.getElementPlain(); /* Likely in sync */
++
++ if (element != null && (element == object || element.equals(object))) {
++ return true;
++ }
++
++ if (next == null || next == curr) {
++ break;
++ }
++ curr = next;
++ }
++
++ return false;
++ }
++
++ /**
++ * Finds the first element in this queue that matches the predicate.
++ * @param predicate The predicate to test elements against.
++ * @return The first element that matched the predicate, {@code null} if none matched.
++ */
++ public E find(final Predicate<E> predicate) {
++ Validate.notNull(predicate, "Null predicate");
++
++ for (LinkedNode<E> curr = this.getHeadOpaque();;) {
++ final LinkedNode<E> next = curr.getNextVolatile();
++ final E element = curr.getElementPlain(); /* Likely in sync */
++
++ if (element != null && predicate.test(element)) {
++ return element;
++ }
++
++ if (next == null || next == curr) {
++ break;
++ }
++ curr = next;
++ }
++
++ return null;
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public void forEach(final Consumer<? super E> action) {
++ Validate.notNull(action, "Null action");
++
++ for (LinkedNode<E> curr = this.getHeadOpaque();;) {
++ final LinkedNode<E> next = curr.getNextVolatile();
++ final E element = curr.getElementPlain(); /* Likely in sync */
++
++ if (element != null) {
++ action.accept(element);
++ }
++
++ if (next == null || next == curr) {
++ break;
++ }
++ curr = next;
++ }
++ }
++
++ // return true if normal addition, false if the queue previously disallowed additions
++ protected final boolean forceAppendList(final LinkedNode<E> head, final LinkedNode<E> tail) {
++ int failures = 0;
++
++ for (LinkedNode<E> currTail = this.getTailOpaque(), curr = currTail;;) {
++ /* It has been experimentally shown that placing the read before the backoff results in significantly greater performance */
++ /* It is likely due to a cache miss caused by another write to the next field */
++ final LinkedNode<E> next = curr.getNextVolatile();
++
++ for (int i = 0; i < failures; ++i) {
++ ConcurrentUtil.backoff();
++ }
++
++ if (next == null || next == curr) {
++ final LinkedNode<E> compared = curr.compareExchangeNextVolatile(next, head);
++
++ if (compared == next) {
++ /* Added */
++ /* Avoid CASing on tail more than we need to */
++ /* "CAS" to avoid setting an out-of-date tail */
++ if (this.getTailOpaque() == currTail) {
++ this.setTailOpaque(tail);
++ }
++ return next != curr;
++ }
++
++ ++failures;
++ curr = compared;
++ continue;
++ }
++
++ if (curr == currTail) {
++ /* Tail is likely not up-to-date */
++ curr = next;
++ } else {
++ /* Try to update to tail */
++ if (currTail == (currTail = this.getTailOpaque())) {
++ curr = next;
++ } else {
++ curr = currTail;
++ }
++ }
++ }
++ }
++
++ // return true if successful, false otherwise
++ protected final boolean appendList(final LinkedNode<E> head, final LinkedNode<E> tail) {
++ int failures = 0;
++
++ for (LinkedNode<E> currTail = this.getTailOpaque(), curr = currTail;;) {
++ /* It has been experimentally shown that placing the read before the backoff results in significantly greater performance */
++ /* It is likely due to a cache miss caused by another write to the next field */
++ final LinkedNode<E> next = curr.getNextVolatile();
++
++ if (next == curr) {
++ /* Additions are stopped */
++ return false;
++ }
++
++ for (int i = 0; i < failures; ++i) {
++ ConcurrentUtil.backoff();
++ }
++
++ if (next == null) {
++ final LinkedNode<E> compared = curr.compareExchangeNextVolatile(null, head);
++
++ if (compared == null) {
++ /* Added */
++ /* Avoid CASing on tail more than we need to */
++ /* CAS to avoid setting an out-of-date tail */
++ if (this.getTailOpaque() == currTail) {
++ this.setTailOpaque(tail);
++ }
++ return true;
++ }
++
++ ++failures;
++ curr = compared;
++ continue;
++ }
++
++ if (curr == currTail) {
++ /* Tail is likely not up-to-date */
++ curr = next;
++ } else {
++ /* Try to update to tail */
++ if (currTail == (currTail = this.getTailOpaque())) {
++ curr = next;
++ } else {
++ curr = currTail;
++ }
++ }
++ }
++ }
++
++ protected final E removeHead(final Predicate<E> predicate) {
++ int failures = 0;
++ for (LinkedNode<E> head = this.getHeadOpaque(), curr = head;;) {
++ // volatile here synchronizes-with writes to element
++ final LinkedNode<E> next = curr.getNextVolatile();
++ final E currentVal = curr.getElementPlain();
++
++ for (int i = 0; i < failures; ++i) {
++ ConcurrentUtil.backoff();
++ }
++
++ if (currentVal != null) {
++ if (!predicate.test(currentVal)) {
++ /* Try to update stale head */
++ if (curr != head && this.getHeadOpaque() == head) {
++ this.setHeadOpaque(curr);
++ }
++ return null;
++ }
++ if (curr.getAndSetElementVolatile(null) == null) {
++ /* Failed to get head */
++ if (curr == (curr = next) || next == null) {
++ return null;
++ }
++ ++failures;
++ continue;
++ }
++
++ /* "CAS" to avoid setting an out-of-date head */
++ if (this.getHeadOpaque() == head) {
++ this.setHeadOpaque(next != null ? next : curr);
++ }
++
++ return currentVal;
++ }
++
++ if (curr == next || next == null) {
++ /* Try to update stale head */
++ if (curr != head && this.getHeadOpaque() == head) {
++ this.setHeadOpaque(curr);
++ }
++ return null; /* End of queue */
++ }
++
++ if (head == curr) {
++ /* head is likely not up-to-date */
++ curr = next;
++ } else {
++ /* Try to update to head */
++ if (head == (head = this.getHeadOpaque())) {
++ curr = next;
++ } else {
++ curr = head;
++ }
++ }
++ }
++ }
++
++ protected final E removeHead() {
++ int failures = 0;
++ for (LinkedNode<E> head = this.getHeadOpaque(), curr = head;;) {
++ final LinkedNode<E> next = curr.getNextVolatile();
++ final E currentVal = curr.getElementPlain();
++
++ for (int i = 0; i < failures; ++i) {
++ ConcurrentUtil.backoff();
++ }
++
++ if (currentVal != null) {
++ if (curr.getAndSetElementVolatile(null) == null) {
++ /* Failed to get head */
++ if (curr == (curr = next) || next == null) {
++ return null;
++ }
++ ++failures;
++ continue;
++ }
++
++ /* "CAS" to avoid setting an out-of-date head */
++ if (this.getHeadOpaque() == head) {
++ this.setHeadOpaque(next != null ? next : curr);
++ }
++
++ return currentVal;
++ }
++
++ if (curr == next || next == null) {
++ /* Try to update stale head */
++ if (curr != head && this.getHeadOpaque() == head) {
++ this.setHeadOpaque(curr);
++ }
++ return null; /* End of queue */
++ }
++
++ if (head == curr) {
++ /* head is likely not up-to-date */
++ curr = next;
++ } else {
++ /* Try to update to head */
++ if (head == (head = this.getHeadOpaque())) {
++ curr = next;
++ } else {
++ curr = head;
++ }
++ }
++ }
++ }
++
++ /**
++ * Empties the queue into the specified consumer. This function is optimized for single-threaded reads, and should
++ * be faster than a loop on {@link #poll()}.
++ * <p>
++ * This function is not MT-Safe. This function cannot be called with other read operations ({@link #peek()}, {@link #poll()},
++ * {@link #clear()}, etc).
++ * Write operations are safe to be called concurrently.
++ * </p>
++ * @param consumer The consumer to accept the elements.
++ * @return The total number of elements drained.
++ */
++ public int drain(final Consumer<E> consumer) {
++ return this.drain(consumer, false, ConcurrentUtil::rethrow);
++ }
++
++ /**
++ * Empties the queue into the specified consumer. This function is optimized for single-threaded reads, and should
++ * be faster than a loop on {@link #poll()}.
++ * <p>
++ * If {@code preventAdds} is {@code true}, then after this function returns the queue is guaranteed to be empty and
++ * additions to the queue will fail.
++ * </p>
++ * <p>
++ * This function is not MT-Safe. This function cannot be called with other read operations ({@link #peek()}, {@link #poll()},
++ * {@link #clear()}, etc).
++ * Write operations are safe to be called concurrently.
++ * </p>
++ * @param consumer The consumer to accept the elements.
++ * @param preventAdds Whether to prevent additions to this queue after draining.
++ * @return The total number of elements drained.
++ */
++ public int drain(final Consumer<E> consumer, final boolean preventAdds) {
++ return this.drain(consumer, preventAdds, ConcurrentUtil::rethrow);
++ }
++
++ /**
++ * Empties the queue into the specified consumer. This function is optimized for single-threaded reads, and should
++ * be faster than a loop on {@link #poll()}.
++ * <p>
++ * If {@code preventAdds} is {@code true}, then after this function returns the queue is guaranteed to be empty and
++ * additions to the queue will fail.
++ * </p>
++ * <p>
++ * This function is not MT-Safe. This function cannot be called with other read operations ({@link #peek()}, {@link #poll()},
++ * {@link #clear()}, {@link #remove(Object)} etc).
++ * Only write operations are safe to be called concurrently.
++ * </p>
++ * @param consumer The consumer to accept the elements.
++ * @param preventAdds Whether to prevent additions to this queue after draining.
++ * @param exceptionHandler Invoked when the consumer raises an exception.
++ * @return The total number of elements drained.
++ */
++ public int drain(final Consumer<E> consumer, final boolean preventAdds, final Consumer<Throwable> exceptionHandler) {
++ Validate.notNull(consumer, "Null consumer");
++ Validate.notNull(exceptionHandler, "Null exception handler");
++
++ /* This function assumes proper synchronization is made to ensure drain and no other read function are called concurrently */
++ /* This allows plain write usages instead of opaque or higher */
++ int total = 0;
++
++ final LinkedNode<E> head = this.getHeadAcquire(); /* Required to synchronize with the write to the first element field */
++ LinkedNode<E> curr = head;
++
++ for (;;) {
++ /* Volatile acquires with the write to the element field */
++ final E currentVal = curr.getElementPlain();
++ LinkedNode<E> next = curr.getNextVolatile();
++
++ if (next == curr) {
++ /* Add-locked nodes always have a null value */
++ break;
++ }
++
++ if (currentVal == null) {
++ if (next == null) {
++ if (preventAdds && (next = curr.compareExchangeNextVolatile(null, curr)) != null) {
++ // failed to prevent adds, continue
++ curr = next;
++ continue;
++ } else {
++ // we're done here
++ break;
++ }
++ }
++ curr = next;
++ continue;
++ }
++
++ try {
++ consumer.accept(currentVal);
++ } catch (final Exception ex) {
++ this.setHeadOpaque(next != null ? next : curr); /* Avoid perf penalty (of reiterating) if the exception handler decides to re-throw */
++ curr.setElementOpaque(null); /* set here, we might re-throw */
++
++ exceptionHandler.accept(ex);
++ }
++
++ curr.setElementOpaque(null);
++
++ ++total;
++
++ if (next == null) {
++ if (preventAdds && (next = curr.compareExchangeNextVolatile(null, curr)) != null) {
++ /* Retry with next value */
++ curr = next;
++ continue;
++ }
++ break;
++ }
++
++ curr = next;
++ }
++ if (curr != head) {
++ this.setHeadOpaque(curr); /* While this may be a plain write, eventually publish it for methods such as find. */
++ }
++ return total;
++ }
++
++ @Override
++ public Spliterator<E> spliterator() { // TODO implement
++ return Spliterators.spliterator(this, Spliterator.CONCURRENT |
++ Spliterator.NONNULL | Spliterator.ORDERED);
++ }
++
++ protected static final class LinkedNode<E> {
++
++ protected volatile Object element;
++ protected volatile LinkedNode<E> next;
++
++ protected static final VarHandle ELEMENT_HANDLE = ConcurrentUtil.getVarHandle(LinkedNode.class, "element", Object.class);
++ protected static final VarHandle NEXT_HANDLE = ConcurrentUtil.getVarHandle(LinkedNode.class, "next", LinkedNode.class);
++
++ protected LinkedNode(final Object element, final LinkedNode<E> next) {
++ ELEMENT_HANDLE.set(this, element);
++ NEXT_HANDLE.set(this, next);
++ }
++
++ /* element */
++
++ @SuppressWarnings("unchecked")
++ protected final E getElementPlain() {
++ return (E)ELEMENT_HANDLE.get(this);
++ }
++
++ @SuppressWarnings("unchecked")
++ protected final E getElementVolatile() {
++ return (E)ELEMENT_HANDLE.getVolatile(this);
++ }
++
++ protected final void setElementPlain(final E update) {
++ ELEMENT_HANDLE.set(this, (Object)update);
++ }
++
++ protected final void setElementOpaque(final E update) {
++ ELEMENT_HANDLE.setOpaque(this, (Object)update);
++ }
++
++ protected final void setElementVolatile(final E update) {
++ ELEMENT_HANDLE.setVolatile(this, (Object)update);
++ }
++
++ @SuppressWarnings("unchecked")
++ protected final E getAndSetElementVolatile(final E update) {
++ return (E)ELEMENT_HANDLE.getAndSet(this, update);
++ }
++
++ @SuppressWarnings("unchecked")
++ protected final E compareExchangeElementVolatile(final E expect, final E update) {
++ return (E)ELEMENT_HANDLE.compareAndExchange(this, expect, update);
++ }
++
++ /* next */
++
++ @SuppressWarnings("unchecked")
++ protected final LinkedNode<E> getNextPlain() {
++ return (LinkedNode<E>)NEXT_HANDLE.get(this);
++ }
++
++ @SuppressWarnings("unchecked")
++ protected final LinkedNode<E> getNextOpaque() {
++ return (LinkedNode<E>)NEXT_HANDLE.getOpaque(this);
++ }
++
++ @SuppressWarnings("unchecked")
++ protected final LinkedNode<E> getNextAcquire() {
++ return (LinkedNode<E>)NEXT_HANDLE.getAcquire(this);
++ }
++
++ @SuppressWarnings("unchecked")
++ protected final LinkedNode<E> getNextVolatile() {
++ return (LinkedNode<E>)NEXT_HANDLE.getVolatile(this);
++ }
++
++ protected final void setNextPlain(final LinkedNode<E> next) {
++ NEXT_HANDLE.set(this, next);
++ }
++
++ protected final void setNextVolatile(final LinkedNode<E> next) {
++ NEXT_HANDLE.setVolatile(this, next);
++ }
++
++ @SuppressWarnings("unchecked")
++ protected final LinkedNode<E> compareExchangeNextVolatile(final LinkedNode<E> expect, final LinkedNode<E> set) {
++ return (LinkedNode<E>)NEXT_HANDLE.compareAndExchange(this, expect, set);
++ }
++ }
++
++ protected static final class LinkedIterator<E> implements Iterator<E> {
++
++ protected LinkedNode<E> curr; /* last returned by next() */
++ protected LinkedNode<E> next; /* next to return from next() */
++ protected E nextElement; /* cached to avoid a race condition with removing or polling */
++
++ protected LinkedIterator(final LinkedNode<E> start) {
++ /* setup nextElement and next */
++ for (LinkedNode<E> curr = start;;) {
++ final LinkedNode<E> next = curr.getNextVolatile();
++
++ final E element = curr.getElementPlain();
++
++ if (element != null) {
++ this.nextElement = element;
++ this.next = curr;
++ break;
++ }
++
++ if (next == null || next == curr) {
++ break;
++ }
++ curr = next;
++ }
++ }
++
++ protected final void findNext() {
++ /* only called if this.nextElement != null, which means this.next != null */
++ for (LinkedNode<E> curr = this.next;;) {
++ final LinkedNode<E> next = curr.getNextVolatile();
++
++ if (next == null || next == curr) {
++ break;
++ }
++
++ final E element = next.getElementPlain();
++
++ if (element != null) {
++ this.nextElement = element;
++ this.curr = this.next; /* this.next will be the value returned from next(), set this.curr for remove() */
++ this.next = next;
++ return;
++ }
++ curr = next;
++ }
++
++ /* out of nodes to iterate */
++ /* keep curr for remove() calls */
++ this.next = null;
++ this.nextElement = null;
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public boolean hasNext() {
++ return this.nextElement != null;
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public E next() {
++ final E element = this.nextElement;
++
++ if (element == null) {
++ throw new NoSuchElementException();
++ }
++
++ this.findNext();
++
++ return element;
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public void remove() {
++ if (this.curr == null) {
++ throw new IllegalStateException();
++ }
++
++ this.curr.setElementVolatile(null);
++ this.curr = null;
++ }
++ }
++}
+diff --git a/src/main/java/ca/spottedleaf/concurrentutil/completable/Completable.java b/src/main/java/ca/spottedleaf/concurrentutil/completable/Completable.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..a1ad3308f9c3545a604b635896259a1cd3382b2a
+--- /dev/null
++++ b/src/main/java/ca/spottedleaf/concurrentutil/completable/Completable.java
+@@ -0,0 +1,98 @@
++package ca.spottedleaf.concurrentutil.completable;
++
++import ca.spottedleaf.concurrentutil.collection.MultiThreadedQueue;
++import ca.spottedleaf.concurrentutil.executor.Cancellable;
++import ca.spottedleaf.concurrentutil.util.ConcurrentUtil;
++import com.mojang.logging.LogUtils;
++import org.slf4j.Logger;
++import java.util.function.BiConsumer;
++
++public final class Completable<T> {
++
++ private static final Logger LOGGER = LogUtils.getLogger();
++
++ private final MultiThreadedQueue<BiConsumer<T, Throwable>> waiters = new MultiThreadedQueue<>();
++ private T result;
++ private Throwable throwable;
++ private volatile boolean completed;
++
++ public boolean isCompleted() {
++ return this.completed;
++ }
++
++ /**
++ * Note: Can only use after calling {@link #addAsynchronousWaiter(BiConsumer)}, as this function performs zero
++ * synchronisation
++ */
++ public T getResult() {
++ return this.result;
++ }
++
++ /**
++ * Note: Can only use after calling {@link #addAsynchronousWaiter(BiConsumer)}, as this function performs zero
++ * synchronisation
++ */
++ public Throwable getThrowable() {
++ return this.throwable;
++ }
++
++ public Cancellable addAsynchronousWaiter(final BiConsumer<T, Throwable> consumer) {
++ if (this.waiters.add(consumer)) {
++ return new CancellableImpl(consumer);
++ }
++ return null;
++ }
++
++ private void completeAllWaiters(final T result, final Throwable throwable) {
++ this.completed = true;
++ BiConsumer<T, Throwable> waiter;
++ while ((waiter = this.waiters.pollOrBlockAdds()) != null) {
++ this.completeWaiter(waiter, result, throwable);
++ }
++ }
++
++ private void completeWaiter(final BiConsumer<T, Throwable> consumer, final T result, final Throwable throwable) {
++ try {
++ consumer.accept(result, throwable);
++ } catch (final ThreadDeath death) {
++ throw death;
++ } catch (final Throwable throwable2) {
++ LOGGER.error("Failed to complete callback " + ConcurrentUtil.genericToString(consumer), throwable2);
++ }
++ }
++
++ public Cancellable addWaiter(final BiConsumer<T, Throwable> consumer) {
++ if (this.waiters.add(consumer)) {
++ return new CancellableImpl(consumer);
++ }
++ this.completeWaiter(consumer, this.result, this.throwable);
++ return new CancellableImpl(consumer);
++ }
++
++ public void complete(final T result) {
++ this.result = result;
++ this.completeAllWaiters(result, null);
++ }
++
++ public void completeWithThrowable(final Throwable throwable) {
++ if (throwable == null) {
++ throw new NullPointerException("Throwable cannot be null");
++ }
++ this.throwable = throwable;
++ this.completeAllWaiters(null, throwable);
++ }
++
++ private final class CancellableImpl implements Cancellable {
++
++ private final BiConsumer<T, Throwable> waiter;
++
++ private CancellableImpl(final BiConsumer<T, Throwable> waiter) {
++ this.waiter = waiter;
++ }
++
++ @Override
++ public boolean cancel() {
++ return Completable.this.waiters.remove(this.waiter);
++ }
++ }
++}
+diff --git a/src/main/java/ca/spottedleaf/concurrentutil/executor/BaseExecutor.java b/src/main/java/ca/spottedleaf/concurrentutil/executor/BaseExecutor.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..716a0fd3f558df748e355069746272facb91de22
+--- /dev/null
++++ b/src/main/java/ca/spottedleaf/concurrentutil/executor/BaseExecutor.java
+@@ -0,0 +1,198 @@
++package ca.spottedleaf.concurrentutil.executor;
++
++import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor;
++import ca.spottedleaf.concurrentutil.util.ConcurrentUtil;
++import java.util.function.BooleanSupplier;
++
++public interface BaseExecutor {
++
++ /**
++ * Returns whether every task scheduled to this queue has been removed and executed or cancelled. If no tasks have been queued,
++ * returns {@code true}.
++ *
++ * @return {@code true} if all tasks that have been queued have finished executing or no tasks have been queued, {@code false} otherwise.
++ */
++ public default boolean haveAllTasksExecuted() {
++ // order is important
++ // if new tasks are scheduled between the reading of these variables, scheduled is guaranteed to be higher -
++ // so our check fails, and we try again
++ final long completed = this.getTotalTasksExecuted();
++ final long scheduled = this.getTotalTasksScheduled();
++
++ return completed == scheduled;
++ }
++
++ /**
++ * Returns the number of tasks that have been scheduled or execute or are pending to be scheduled.
++ */
++ public long getTotalTasksScheduled();
++
++ /**
++ * Returns the number of tasks that have fully been executed.
++ */
++ public long getTotalTasksExecuted();
++
++
++ /**
++ * Waits until this queue has had all of its tasks executed (NOT removed). See {@link #haveAllTasksExecuted()}
++ * <p>
++ * This call is most effective after a {@link #shutdown()} call, as the shutdown call guarantees no tasks can
++ * be executed and the waitUntilAllExecuted call makes sure the queue is empty. Effectively, using shutdown then using
++ * waitUntilAllExecuted ensures this queue is empty - and most importantly, will remain empty.
++ * </p>
++ * <p>
++ * This method is not guaranteed to be immediately responsive to queue state, so calls may take significantly more
++ * time than expected. Effectively, do not rely on this call being fast - even if there are few tasks scheduled.
++ * </p>
++ * <p>
++ * Note: Interruptions to the the current thread have no effect. Interrupt status is also not affected by this cal.
++ * </p>
++ *
++ * @throws IllegalStateException If the current thread is not allowed to wait
++ */
++ public default void waitUntilAllExecuted() throws IllegalStateException {
++ long failures = 9L; // start out at 1ms
++
++ while (!this.haveAllTasksExecuted()) {
++ Thread.yield();
++ failures = ConcurrentUtil.linearLongBackoff(failures, 500_000L, 5_000_000L); // 500us, 5ms
++ }
++ }
++
++ /**
++ * Executes the next available task.
++ * <p>
++ * If there is a task with priority {@link PrioritisedExecutor.Priority#BLOCKING} available, then that such task is executed.
++ * </p>
++ * <p>
++ * If there is a task with priority {@link PrioritisedExecutor.Priority#IDLE} available then that task is only executed
++ * when there are no other tasks available with a higher priority.
++ * </p>
++ * <p>
++ * If there are no tasks that have priority {@link PrioritisedExecutor.Priority#BLOCKING} or {@link PrioritisedExecutor.Priority#IDLE}, then
++ * this function will be biased to execute tasks that have higher priorities.
++ * </p>
++ *
++ * @return {@code true} if a task was executed, {@code false} otherwise
++ * @throws IllegalStateException If the current thread is not allowed to execute a task
++ */
++ public boolean executeTask() throws IllegalStateException;
++
++ /**
++ * Executes all queued tasks.
++ *
++ * @return {@code true} if a task was executed, {@code false} otherwise
++ * @throws IllegalStateException If the current thread is not allowed to execute a task
++ */
++ public default boolean executeAll() {
++ if (!this.executeTask()) {
++ return false;
++ }
++
++ while (this.executeTask());
++
++ return true;
++ }
++
++ /**
++ * Waits and executes tasks until the condition returns {@code true}.
++ * <p>
++ * WARNING: This function is <i>not</i> suitable for waiting until a deadline!
++ * Use {@link #executeUntil(long)} or {@link #executeConditionally(BooleanSupplier, long)} instead.
++ * </p>
++ */
++ public default void executeConditionally(final BooleanSupplier condition) {
++ long failures = 0;
++ while (!condition.getAsBoolean()) {
++ if (this.executeTask()) {
++ failures = failures >>> 2;
++ } else {
++ failures = ConcurrentUtil.linearLongBackoff(failures, 100_000L, 10_000_000L); // 100us, 10ms
++ }
++ }
++ }
++
++ /**
++ * Waits and executes tasks until the condition returns {@code true} or {@code System.nanoTime() >= deadline}.
++ */
++ public default void executeConditionally(final BooleanSupplier condition, final long deadline) {
++ long failures = 0;
++ // double check deadline; we don't know how expensive the condition is
++ while ((System.nanoTime() < deadline) && !condition.getAsBoolean() && (System.nanoTime() < deadline)) {
++ if (this.executeTask()) {
++ failures = failures >>> 2;
++ } else {
++ failures = ConcurrentUtil.linearLongBackoffDeadline(failures, 100_000L, 10_000_000L, deadline); // 100us, 10ms
++ }
++ }
++ }
++
++ /**
++ * Waits and executes tasks until {@code System.nanoTime() >= deadline}.
++ */
++ public default void executeUntil(final long deadline) {
++ long failures = 0;
++ while (System.nanoTime() < deadline) {
++ if (this.executeTask()) {
++ failures = failures >>> 2;
++ } else {
++ failures = ConcurrentUtil.linearLongBackoffDeadline(failures, 100_000L, 10_000_000L, deadline); // 100us, 10ms
++ }
++ }
++ }
++
++ /**
++ * Prevent further additions to this queue. Attempts to add after this call has completed (potentially during) will
++ * result in {@link IllegalStateException} being thrown.
++ * <p>
++ * This operation is atomic with respect to other shutdown calls
++ * </p>
++ * <p>
++ * After this call has completed, regardless of return value, this queue will be shutdown.
++ * </p>
++ *
++ * @return {@code true} if the queue was shutdown, {@code false} if it has shut down already
++ * @throws UnsupportedOperationException If this queue does not support shutdown
++ */
++ public default boolean shutdown() throws UnsupportedOperationException {
++ throw new UnsupportedOperationException();
++ }
++
++ /**
++ * Returns whether this queue has shut down. Effectively, whether new tasks will be rejected - this method
++ * does not indicate whether all of the tasks scheduled have been executed.
++ * @return Returns whether this queue has shut down.
++ */
++ public default boolean isShutdown() {
++ return false;
++ }
++
++ public static interface BaseTask extends Cancellable {
++
++ /**
++ * Causes a lazily queued task to become queued or executed
++ *
++ * @throws IllegalStateException If the backing queue has shutdown
++ * @return {@code true} If the task was queued, {@code false} if the task was already queued/cancelled/executed
++ */
++ public boolean queue();
++
++ /**
++ * Forces this task to be marked as completed.
++ *
++ * @return {@code true} if the task was cancelled, {@code false} if the task has already completed or is being completed.
++ */
++ @Override
++ public boolean cancel();
++
++ /**
++ * Executes this task. This will also mark the task as completing.
++ * <p>
++ * Exceptions thrown from the runnable will be rethrown.
++ * </p>
++ *
++ * @return {@code true} if this task was executed, {@code false} if it was already marked as completed.
++ */
++ public boolean execute();
++ }
++}
+diff --git a/src/main/java/ca/spottedleaf/concurrentutil/executor/Cancellable.java b/src/main/java/ca/spottedleaf/concurrentutil/executor/Cancellable.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..11449056361bb6c5a055f543cdd135c4113757c6
+--- /dev/null
++++ b/src/main/java/ca/spottedleaf/concurrentutil/executor/Cancellable.java
+@@ -0,0 +1,14 @@
++package ca.spottedleaf.concurrentutil.executor;
++
++/**
++ * Interface specifying that something can be cancelled.
++ */
++public interface Cancellable {
++
++ /**
++ * Tries to cancel this task. If the task is in a stage that is too late to be cancelled, then this function
++ * will return {@code false}. If the task is already cancelled, then this function returns {@code false}. Only
++ * when this function successfully stops this task from being completed will it return {@code true}.
++ */
++ public boolean cancel();
++}
+diff --git a/src/main/java/ca/spottedleaf/concurrentutil/executor/standard/DelayedPrioritisedTask.java b/src/main/java/ca/spottedleaf/concurrentutil/executor/standard/DelayedPrioritisedTask.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..3ce10053d4ec51855ad7012abb5d97df1c0e557a
+--- /dev/null
++++ b/src/main/java/ca/spottedleaf/concurrentutil/executor/standard/DelayedPrioritisedTask.java
+@@ -0,0 +1,170 @@
++package ca.spottedleaf.concurrentutil.executor.standard;
++
++import ca.spottedleaf.concurrentutil.util.ConcurrentUtil;
++import java.lang.invoke.VarHandle;
++
++public class DelayedPrioritisedTask {
++
++ protected volatile int priority;
++ protected static final VarHandle PRIORITY_HANDLE = ConcurrentUtil.getVarHandle(DelayedPrioritisedTask.class, "priority", int.class);
++
++ protected static final int PRIORITY_SET = Integer.MIN_VALUE >>> 0;
++
++ protected final int getPriorityVolatile() {
++ return (int)PRIORITY_HANDLE.getVolatile((DelayedPrioritisedTask)this);
++ }
++
++ protected final int compareAndExchangePriorityVolatile(final int expect, final int update) {
++ return (int)PRIORITY_HANDLE.compareAndExchange((DelayedPrioritisedTask)this, (int)expect, (int)update);
++ }
++
++ protected final int getAndOrPriorityVolatile(final int val) {
++ return (int)PRIORITY_HANDLE.getAndBitwiseOr((DelayedPrioritisedTask)this, (int)val);
++ }
++
++ protected final void setPriorityPlain(final int val) {
++ PRIORITY_HANDLE.set((DelayedPrioritisedTask)this, (int)val);
++ }
++
++ protected volatile PrioritisedExecutor.PrioritisedTask task;
++ protected static final VarHandle TASK_HANDLE = ConcurrentUtil.getVarHandle(DelayedPrioritisedTask.class, "task", PrioritisedExecutor.PrioritisedTask.class);
++
++ protected PrioritisedExecutor.PrioritisedTask getTaskPlain() {
++ return (PrioritisedExecutor.PrioritisedTask)TASK_HANDLE.get((DelayedPrioritisedTask)this);
++ }
++
++ protected PrioritisedExecutor.PrioritisedTask getTaskVolatile() {
++ return (PrioritisedExecutor.PrioritisedTask)TASK_HANDLE.getVolatile((DelayedPrioritisedTask)this);
++ }
++
++ protected final PrioritisedExecutor.PrioritisedTask compareAndExchangeTaskVolatile(final PrioritisedExecutor.PrioritisedTask expect, final PrioritisedExecutor.PrioritisedTask update) {
++ return (PrioritisedExecutor.PrioritisedTask)TASK_HANDLE.compareAndExchange((DelayedPrioritisedTask)this, (PrioritisedExecutor.PrioritisedTask)expect, (PrioritisedExecutor.PrioritisedTask)update);
++ }
++
++ public DelayedPrioritisedTask(final PrioritisedExecutor.Priority priority) {
++ this.setPriorityPlain(priority.priority);
++ }
++
++ // only public for debugging
++ public int getPriorityInternal() {
++ return this.getPriorityVolatile();
++ }
++
++ public PrioritisedExecutor.PrioritisedTask getTask() {
++ return this.getTaskVolatile();
++ }
++
++ public void setTask(final PrioritisedExecutor.PrioritisedTask task) {
++ int priority = this.getPriorityVolatile();
++
++ if (this.compareAndExchangeTaskVolatile(null, task) != null) {
++ throw new IllegalStateException("setTask() called twice");
++ }
++
++ int failures = 0;
++ for (;;) {
++ task.setPriority(PrioritisedExecutor.Priority.getPriority(priority));
++
++ if (priority == (priority = this.compareAndExchangePriorityVolatile(priority, priority | PRIORITY_SET))) {
++ return;
++ }
++
++ ++failures;
++ for (int i = 0; i < failures; ++i) {
++ ConcurrentUtil.backoff();
++ }
++ }
++ }
++
++ public PrioritisedExecutor.Priority getPriority() {
++ final int priority = this.getPriorityVolatile();
++ if ((priority & PRIORITY_SET) != 0) {
++ return this.task.getPriority();
++ }
++
++ return PrioritisedExecutor.Priority.getPriority(priority);
++ }
++
++ public void raisePriority(final PrioritisedExecutor.Priority priority) {
++ if (!PrioritisedExecutor.Priority.isValidPriority(priority)) {
++ throw new IllegalArgumentException("Invalid priority " + priority);
++ }
++
++ int failures = 0;
++ for (int curr = this.getPriorityVolatile();;) {
++ if ((curr & PRIORITY_SET) != 0) {
++ this.getTaskPlain().raisePriority(priority);
++ return;
++ }
++
++ if (!priority.isLowerPriority(curr)) {
++ return;
++ }
++
++ if (curr == (curr = this.compareAndExchangePriorityVolatile(curr, priority.priority))) {
++ return;
++ }
++
++ // failed, retry
++
++ ++failures;
++ for (int i = 0; i < failures; ++i) {
++ ConcurrentUtil.backoff();
++ }
++ }
++ }
++
++ public void setPriority(final PrioritisedExecutor.Priority priority) {
++ if (!PrioritisedExecutor.Priority.isValidPriority(priority)) {
++ throw new IllegalArgumentException("Invalid priority " + priority);
++ }
++
++ int failures = 0;
++ for (int curr = this.getPriorityVolatile();;) {
++ if ((curr & PRIORITY_SET) != 0) {
++ this.getTaskPlain().setPriority(priority);
++ return;
++ }
++
++ if (curr == (curr = this.compareAndExchangePriorityVolatile(curr, priority.priority))) {
++ return;
++ }
++
++ // failed, retry
++
++ ++failures;
++ for (int i = 0; i < failures; ++i) {
++ ConcurrentUtil.backoff();
++ }
++ }
++ }
++
++ public void lowerPriority(final PrioritisedExecutor.Priority priority) {
++ if (!PrioritisedExecutor.Priority.isValidPriority(priority)) {
++ throw new IllegalArgumentException("Invalid priority " + priority);
++ }
++
++ int failures = 0;
++ for (int curr = this.getPriorityVolatile();;) {
++ if ((curr & PRIORITY_SET) != 0) {
++ this.getTaskPlain().lowerPriority(priority);
++ return;
++ }
++
++ if (!priority.isHigherPriority(curr)) {
++ return;
++ }
++
++ if (curr == (curr = this.compareAndExchangePriorityVolatile(curr, priority.priority))) {
++ return;
++ }
++
++ // failed, retry
++
++ ++failures;
++ for (int i = 0; i < failures; ++i) {
++ ConcurrentUtil.backoff();
++ }
++ }
++ }
++}
+diff --git a/src/main/java/ca/spottedleaf/concurrentutil/executor/standard/PrioritisedExecutor.java b/src/main/java/ca/spottedleaf/concurrentutil/executor/standard/PrioritisedExecutor.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..e5d8ff730ba9d83efc2d80782de313a718bf55b3
+--- /dev/null
++++ b/src/main/java/ca/spottedleaf/concurrentutil/executor/standard/PrioritisedExecutor.java
+@@ -0,0 +1,246 @@
++package ca.spottedleaf.concurrentutil.executor.standard;
++
++import ca.spottedleaf.concurrentutil.executor.BaseExecutor;
++
++public interface PrioritisedExecutor extends BaseExecutor {
++
++ public static enum Priority {
++
++ /**
++ * Priority value indicating the task has completed or is being completed.
++ * This priority cannot be used to schedule tasks.
++ */
++ COMPLETING(-1),
++
++ /**
++ * Absolute highest priority, should only be used for when a task is blocking a time-critical thread.
++ */
++ BLOCKING(),
++
++ /**
++ * Should only be used for urgent but not time-critical tasks.
++ */
++ HIGHEST(),
++
++ /**
++ * Two priorities above normal.
++ */
++ HIGHER(),
++
++ /**
++ * One priority above normal.
++ */
++ HIGH(),
++
++ /**
++ * Default priority.
++ */
++ NORMAL(),
++
++ /**
++ * One priority below normal.
++ */
++ LOW(),
++
++ /**
++ * Two priorities below normal.
++ */
++ LOWER(),
++
++ /**
++ * Use for tasks that should eventually execute, but are not needed to.
++ */
++ LOWEST(),
++
++ /**
++ * Use for tasks that can be delayed indefinitely.
++ */
++ IDLE();
++
++ // returns whether the priority can be scheduled
++ public static boolean isValidPriority(final Priority priority) {
++ return priority != null && priority != Priority.COMPLETING;
++ }
++
++ // returns the higher priority of the two
++ public static PrioritisedExecutor.Priority max(final Priority p1, final Priority p2) {
++ return p1.isHigherOrEqualPriority(p2) ? p1 : p2;
++ }
++
++ // returns the lower priroity of the two
++ public static PrioritisedExecutor.Priority min(final Priority p1, final Priority p2) {
++ return p1.isLowerOrEqualPriority(p2) ? p1 : p2;
++ }
++
++ public boolean isHigherOrEqualPriority(final Priority than) {
++ return this.priority <= than.priority;
++ }
++
++ public boolean isHigherPriority(final Priority than) {
++ return this.priority < than.priority;
++ }
++
++ public boolean isLowerOrEqualPriority(final Priority than) {
++ return this.priority >= than.priority;
++ }
++
++ public boolean isLowerPriority(final Priority than) {
++ return this.priority > than.priority;
++ }
++
++ public boolean isHigherOrEqualPriority(final int than) {
++ return this.priority <= than;
++ }
++
++ public boolean isHigherPriority(final int than) {
++ return this.priority < than;
++ }
++
++ public boolean isLowerOrEqualPriority(final int than) {
++ return this.priority >= than;
++ }
++
++ public boolean isLowerPriority(final int than) {
++ return this.priority > than;
++ }
++
++ public static boolean isHigherOrEqualPriority(final int priority, final int than) {
++ return priority <= than;
++ }
++
++ public static boolean isHigherPriority(final int priority, final int than) {
++ return priority < than;
++ }
++
++ public static boolean isLowerOrEqualPriority(final int priority, final int than) {
++ return priority >= than;
++ }
++
++ public static boolean isLowerPriority(final int priority, final int than) {
++ return priority > than;
++ }
++
++ static final PrioritisedExecutor.Priority[] PRIORITIES = PrioritisedExecutor.Priority.values();
++
++ /** includes special priorities */
++ public static final int TOTAL_PRIORITIES = PRIORITIES.length;
++
++ public static final int TOTAL_SCHEDULABLE_PRIORITIES = TOTAL_PRIORITIES - 1;
++
++ public static PrioritisedExecutor.Priority getPriority(final int priority) {
++ return PRIORITIES[priority + 1];
++ }
++
++ private static int priorityCounter;
++
++ private static int nextCounter() {
++ return priorityCounter++;
++ }
++
++ public final int priority;
++
++ Priority() {
++ this(nextCounter());
++ }
++
++ Priority(final int priority) {
++ this.priority = priority;
++ }
++ }
++
++ /**
++ * Queues or executes a task at {@link Priority#NORMAL} priority.
++ * @param task The task to run.
++ *
++ * @throws IllegalStateException If this queue has shutdown.
++ * @throws NullPointerException If the task is null
++ * @return {@code null} if the current thread immediately executed the task, else returns the prioritised task
++ * associated with the parameter
++ */
++ public default PrioritisedTask queueRunnable(final Runnable task) {
++ return this.queueRunnable(task, PrioritisedExecutor.Priority.NORMAL);
++ }
++
++ /**
++ * Queues or executes a task.
++ *
++ * @param task The task to run.
++ * @param priority The priority for the task.
++ *
++ * @throws IllegalStateException If this queue has shutdown.
++ * @throws NullPointerException If the task is null
++ * @throws IllegalArgumentException If the priority is invalid.
++ * @return {@code null} if the current thread immediately executed the task, else returns the prioritised task
++ * associated with the parameter
++ */
++ public PrioritisedTask queueRunnable(final Runnable task, final PrioritisedExecutor.Priority priority);
++
++ /**
++ * Creates, but does not execute or queue the task. The task must later be queued via {@link BaseExecutor.BaseTask#queue()}.
++ *
++ * @param task The task to run.
++ *
++ * @throws IllegalStateException If this queue has shutdown.
++ * @throws NullPointerException If the task is null
++ * @throws IllegalArgumentException If the priority is invalid.
++ * @throws UnsupportedOperationException If this executor does not support lazily queueing tasks
++ * @return The prioritised task associated with the parameters
++ */
++ public default PrioritisedExecutor.PrioritisedTask createTask(final Runnable task) {
++ return this.createTask(task, PrioritisedExecutor.Priority.NORMAL);
++ }
++
++ /**
++ * Creates, but does not execute or queue the task. The task must later be queued via {@link BaseExecutor.BaseTask#queue()}.
++ *
++ * @param task The task to run.
++ * @param priority The priority for the task.
++ *
++ * @throws IllegalStateException If this queue has shutdown.
++ * @throws NullPointerException If the task is null
++ * @throws IllegalArgumentException If the priority is invalid.
++ * @throws UnsupportedOperationException If this executor does not support lazily queueing tasks
++ * @return The prioritised task associated with the parameters
++ */
++ public PrioritisedExecutor.PrioritisedTask createTask(final Runnable task, final PrioritisedExecutor.Priority priority);
++
++ public static interface PrioritisedTask extends BaseTask {
++
++ /**
++ * Returns the current priority. Note that {@link PrioritisedExecutor.Priority#COMPLETING} will be returned
++ * if this task is completing or has completed.
++ */
++ public PrioritisedExecutor.Priority getPriority();
++
++ /**
++ * Attempts to set this task's priority level to the level specified.
++ *
++ * @param priority Specified priority level.
++ *
++ * @throws IllegalArgumentException If the priority is invalid
++ * @return {@code true} if successful, {@code false} if this task is completing or has completed or the queue
++ * this task was scheduled on was shutdown, or if the priority was already at the specified level.
++ */
++ public boolean setPriority(final PrioritisedExecutor.Priority priority);
++
++ /**
++ * Attempts to raise the priority to the priority level specified.
++ *
++ * @param priority Priority specified
++ *
++ * @throws IllegalArgumentException If the priority is invalid
++ * @return {@code false} if the current task is completing, {@code true} if the priority was raised to the specified level or was already at the specified level or higher.
++ */
++ public boolean raisePriority(final PrioritisedExecutor.Priority priority);
++
++ /**
++ * Attempts to lower the priority to the priority level specified.
++ *
++ * @param priority Priority specified
++ *
++ * @throws IllegalArgumentException If the priority is invalid
++ * @return {@code false} if the current task is completing, {@code true} if the priority was lowered to the specified level or was already at the specified level or lower.
++ */
++ public boolean lowerPriority(final PrioritisedExecutor.Priority priority);
++ }
++}
+diff --git a/src/main/java/ca/spottedleaf/concurrentutil/executor/standard/PrioritisedQueueExecutorThread.java b/src/main/java/ca/spottedleaf/concurrentutil/executor/standard/PrioritisedQueueExecutorThread.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..91fe0f7049122f62f05ba09c24cba5d758340cff
+--- /dev/null
++++ b/src/main/java/ca/spottedleaf/concurrentutil/executor/standard/PrioritisedQueueExecutorThread.java
+@@ -0,0 +1,297 @@
++package ca.spottedleaf.concurrentutil.executor.standard;
++
++import ca.spottedleaf.concurrentutil.util.ConcurrentUtil;
++import com.mojang.logging.LogUtils;
++import org.slf4j.Logger;
++import java.lang.invoke.VarHandle;
++import java.util.concurrent.locks.LockSupport;
++
++/**
++ * Thread which will continuously drain from a specified queue.
++ * <p>
++ * Note: When using this thread, queue additions to the underlying {@link #queue} are not sufficient to get this thread
++ * to execute the task. The function {@link #notifyTasks()} must be used after scheduling a task. For expected behaviour
++ * of task scheduling (thread wakes up after tasks are scheduled), use the methods provided on {@link PrioritisedExecutor}
++ * methods.
++ * </p>
++ */
++public class PrioritisedQueueExecutorThread extends Thread implements PrioritisedExecutor {
++
++ private static final Logger LOGGER = LogUtils.getLogger();
++
++ protected final PrioritisedExecutor queue;
++
++ protected volatile boolean threadShutdown;
++
++ protected static final VarHandle THREAD_PARKED_HANDLE = ConcurrentUtil.getVarHandle(PrioritisedQueueExecutorThread.class, "threadParked", boolean.class);
++ protected volatile boolean threadParked;
++
++ protected volatile boolean halted;
++
++ protected final long spinWaitTime;
++
++ static final long DEFAULT_SPINWAIT_TIME = (long)(0.1e6);// 0.1ms
++
++ public PrioritisedQueueExecutorThread(final PrioritisedExecutor queue) {
++ this(queue, DEFAULT_SPINWAIT_TIME); // 0.1ms
++ }
++
++ public PrioritisedQueueExecutorThread(final PrioritisedExecutor queue, final long spinWaitTime) { // in ns
++ this.queue = queue;
++ this.spinWaitTime = spinWaitTime;
++ }
++
++ @Override
++ public void run() {
++ final long spinWaitTime = this.spinWaitTime;
++
++ main_loop:
++ for (;;) {
++ this.pollTasks();
++
++ // spinwait
++
++ final long start = System.nanoTime();
++
++ for (;;) {
++ // If we are interrupted for any reason, park() will always return immediately. Clear so that we don't needlessly use cpu in such an event.
++ Thread.interrupted();
++ Thread.yield();
++ LockSupport.parkNanos("Spinwaiting on tasks", 10_000L); // 10us
++
++ if (this.pollTasks()) {
++ // restart loop, found tasks
++ continue main_loop;
++ }
++
++ if (this.handleClose()) {
++ return; // we're done
++ }
++
++ if ((System.nanoTime() - start) >= spinWaitTime) {
++ break;
++ }
++ }
++
++ if (this.handleClose()) {
++ return;
++ }
++
++ this.setThreadParkedVolatile(true);
++
++ // We need to parse here to avoid a race condition where a thread queues a task before we set parked to true
++ // (i.e it will not notify us)
++ if (this.pollTasks()) {
++ this.setThreadParkedVolatile(false);
++ continue;
++ }
++
++ if (this.handleClose()) {
++ return;
++ }
++
++ // we don't need to check parked before sleeping, but we do need to check parked in a do-while loop
++ // LockSupport.park() can fail for any reason
++ while (this.getThreadParkedVolatile()) {
++ Thread.interrupted();
++ LockSupport.park("Waiting on tasks");
++ }
++ }
++ }
++
++ protected boolean pollTasks() {
++ boolean ret = false;
++
++ for (;;) {
++ if (this.halted) {
++ break;
++ }
++ try {
++ if (!this.queue.executeTask()) {
++ break;
++ }
++ ret = true;
++ } catch (final ThreadDeath death) {
++ throw death; // goodbye world...
++ } catch (final Throwable throwable) {
++ LOGGER.error("Exception thrown from prioritized runnable task in thread '" + this.getName() + "'", throwable);
++ }
++ }
++
++ return ret;
++ }
++
++ protected boolean handleClose() {
++ if (this.threadShutdown) {
++ this.pollTasks(); // this ensures we've emptied the queue
++ return true;
++ }
++ return false;
++ }
++
++ /**
++ * Notify this thread that a task has been added to its queue
++ * @return {@code true} if this thread was waiting for tasks, {@code false} if it is executing tasks
++ */
++ public boolean notifyTasks() {
++ if (this.getThreadParkedVolatile() && this.exchangeThreadParkedVolatile(false)) {
++ LockSupport.unpark(this);
++ return true;
++ }
++ return false;
++ }
++
++ @Override
++ public PrioritisedTask createTask(final Runnable task, final Priority priority) {
++ final PrioritisedExecutor.PrioritisedTask queueTask = this.queue.createTask(task, priority);
++
++ // need to override queue() to notify us of tasks
++ return new PrioritisedTask() {
++ @Override
++ public Priority getPriority() {
++ return queueTask.getPriority();
++ }
++
++ @Override
++ public boolean setPriority(final Priority priority) {
++ return queueTask.setPriority(priority);
++ }
++
++ @Override
++ public boolean raisePriority(final Priority priority) {
++ return queueTask.raisePriority(priority);
++ }
++
++ @Override
++ public boolean lowerPriority(final Priority priority) {
++ return queueTask.lowerPriority(priority);
++ }
++
++ @Override
++ public boolean queue() {
++ final boolean ret = queueTask.queue();
++ if (ret) {
++ PrioritisedQueueExecutorThread.this.notifyTasks();
++ }
++ return ret;
++ }
++
++ @Override
++ public boolean cancel() {
++ return queueTask.cancel();
++ }
++
++ @Override
++ public boolean execute() {
++ return queueTask.execute();
++ }
++ };
++ }
++
++ @Override
++ public PrioritisedExecutor.PrioritisedTask queueRunnable(final Runnable task, final PrioritisedExecutor.Priority priority) {
++ final PrioritisedExecutor.PrioritisedTask ret = this.queue.queueRunnable(task, priority);
++
++ this.notifyTasks();
++
++ return ret;
++ }
++
++ @Override
++ public boolean haveAllTasksExecuted() {
++ return this.queue.haveAllTasksExecuted();
++ }
++
++ @Override
++ public long getTotalTasksExecuted() {
++ return this.queue.getTotalTasksExecuted();
++ }
++
++ @Override
++ public long getTotalTasksScheduled() {
++ return this.queue.getTotalTasksScheduled();
++ }
++
++ /**
++ * {@inheritDoc}
++ * @throws IllegalStateException If the current thread is {@code this} thread, or the underlying queue throws this exception.
++ */
++ @Override
++ public void waitUntilAllExecuted() throws IllegalStateException {
++ if (Thread.currentThread() == this) {
++ throw new IllegalStateException("Cannot block on our own queue");
++ }
++ this.queue.waitUntilAllExecuted();
++ }
++
++ /**
++ * {@inheritDoc}
++ * @throws IllegalStateException Always
++ */
++ @Override
++ public boolean executeTask() throws IllegalStateException {
++ throw new IllegalStateException();
++ }
++
++ /**
++ * Closes this queue executor's queue. Optionally waits for all tasks in queue to be executed if {@code wait} is true.
++ * <p>
++ * This function is MT-Safe.
++ * </p>
++ * @param wait If this call is to wait until the queue is empty and there are no tasks executing in the queue.
++ * @param killQueue Whether to shutdown this thread's queue
++ * @return whether this thread shut down the queue
++ * @see #halt(boolean)
++ */
++ public boolean close(final boolean wait, final boolean killQueue) {
++ final boolean ret = killQueue && this.queue.shutdown();
++ this.threadShutdown = true;
++
++ // force thread to respond to the shutdown
++ this.setThreadParkedVolatile(false);
++ LockSupport.unpark(this);
++
++ if (wait) {
++ this.waitUntilAllExecuted();
++ }
++
++ return ret;
++ }
++
++
++ /**
++ * Causes this thread to exit without draining the queue. To ensure tasks are completed, use {@link #close(boolean, boolean)}.
++ * <p>
++ * This is not safe to call with {@link #close(boolean, boolean)} if <code>wait = true</code>, in which case
++ * the waiting thread may block indefinitely.
++ * </p>
++ * <p>
++ * This function is MT-Safe.
++ * </p>
++ * @param killQueue Whether to shutdown this thread's queue
++ * @see #close(boolean, boolean)
++ */
++ public void halt(final boolean killQueue) {
++ if (killQueue) {
++ this.queue.shutdown();
++ }
++ this.threadShutdown = true;
++ this.halted = true;
++
++ // force thread to respond to the shutdown
++ this.setThreadParkedVolatile(false);
++ LockSupport.unpark(this);
++ }
++
++ protected final boolean getThreadParkedVolatile() {
++ return (boolean)THREAD_PARKED_HANDLE.getVolatile(this);
++ }
++
++ protected final boolean exchangeThreadParkedVolatile(final boolean value) {
++ return (boolean)THREAD_PARKED_HANDLE.getAndSet(this, value);
++ }
++
++ protected final void setThreadParkedVolatile(final boolean value) {
++ THREAD_PARKED_HANDLE.setVolatile(this, value);
++ }
++}
+diff --git a/src/main/java/ca/spottedleaf/concurrentutil/executor/standard/PrioritisedThreadPool.java b/src/main/java/ca/spottedleaf/concurrentutil/executor/standard/PrioritisedThreadPool.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..26fa2caa18a9194e57574a4a7fa9f7a4265740e0
+--- /dev/null
++++ b/src/main/java/ca/spottedleaf/concurrentutil/executor/standard/PrioritisedThreadPool.java
+@@ -0,0 +1,579 @@
++package ca.spottedleaf.concurrentutil.executor.standard;
++
++import com.mojang.logging.LogUtils;
++import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet;
++import org.slf4j.Logger;
++import java.util.ArrayList;
++import java.util.Arrays;
++import java.util.Comparator;
++import java.util.TreeSet;
++import java.util.concurrent.atomic.AtomicBoolean;
++import java.util.function.BiConsumer;
++
++public final class PrioritisedThreadPool {
++
++ private static final Logger LOGGER = LogUtils.getLogger();
++
++ protected final PrioritisedThread[] threads;
++ protected final TreeSet<PrioritisedPoolExecutorImpl> queues = new TreeSet<>(PrioritisedPoolExecutorImpl.comparator());
++ protected final String name;
++ protected final long queueMaxHoldTime;
++
++ protected final ReferenceOpenHashSet<PrioritisedPoolExecutorImpl> nonShutdownQueues = new ReferenceOpenHashSet<>();
++ protected final ReferenceOpenHashSet<PrioritisedPoolExecutorImpl> activeQueues = new ReferenceOpenHashSet<>();
++
++ protected boolean shutdown;
++
++ protected long schedulingIdGenerator;
++
++ protected static final long DEFAULT_QUEUE_HOLD_TIME = (long)(5.0e6);
++
++ public PrioritisedThreadPool(final String name, final int threads) {
++ this(name, threads, null);
++ }
++
++ public PrioritisedThreadPool(final String name, final int threads, final BiConsumer<Thread, Integer> threadModifier) {
++ this(name, threads, threadModifier, DEFAULT_QUEUE_HOLD_TIME); // 5ms
++ }
++
++ public PrioritisedThreadPool(final String name, final int threads, final BiConsumer<Thread, Integer> threadModifier,
++ final long queueHoldTime) { // in ns
++ if (threads <= 0) {
++ throw new IllegalArgumentException("Thread count must be > 0, not " + threads);
++ }
++ if (name == null) {
++ throw new IllegalArgumentException("Name cannot be null");
++ }
++ this.name = name;
++ this.queueMaxHoldTime = queueHoldTime;
++
++ this.threads = new PrioritisedThread[threads];
++ for (int i = 0; i < threads; ++i) {
++ this.threads[i] = new PrioritisedThread(this);
++
++ // set default attributes
++ this.threads[i].setName("Prioritised thread for pool '" + name + "' #" + i);
++ this.threads[i].setUncaughtExceptionHandler((final Thread thread, final Throwable throwable) -> {
++ LOGGER.error("Uncaught exception in thread " + thread.getName(), throwable);
++ });
++
++ // let thread modifier override defaults
++ if (threadModifier != null) {
++ threadModifier.accept(this.threads[i], Integer.valueOf(i));
++ }
++
++ // now the thread can start
++ this.threads[i].start();
++ }
++ }
++
++ public Thread[] getThreads() {
++ return Arrays.copyOf(this.threads, this.threads.length, Thread[].class);
++ }
++
++ public PrioritisedPoolExecutor createExecutor(final String name, final int parallelism) {
++ synchronized (this.nonShutdownQueues) {
++ if (this.shutdown) {
++ throw new IllegalStateException("Queue is shutdown: " + this.toString());
++ }
++ final PrioritisedPoolExecutorImpl ret = new PrioritisedPoolExecutorImpl(this, name, Math.min(Math.max(1, parallelism), this.threads.length));
++
++ this.nonShutdownQueues.add(ret);
++
++ synchronized (this.activeQueues) {
++ this.activeQueues.add(ret);
++ }
++
++ return ret;
++ }
++ }
++
++ /**
++ * Prevents creation of new queues, shutdowns all non-shutdown queues if specified
++ */
++ public void halt(final boolean shutdownQueues) {
++ synchronized (this.nonShutdownQueues) {
++ this.shutdown = true;
++ }
++ if (shutdownQueues) {
++ final ArrayList<PrioritisedPoolExecutorImpl> queuesToShutdown;
++ synchronized (this.nonShutdownQueues) {
++ this.shutdown = true;
++ queuesToShutdown = new ArrayList<>(this.nonShutdownQueues);
++ }
++
++ for (final PrioritisedPoolExecutorImpl queue : queuesToShutdown) {
++ queue.shutdown();
++ }
++ }
++
++
++ for (final PrioritisedThread thread : this.threads) {
++ // can't kill queue, queue is null
++ thread.halt(false);
++ }
++ }
++
++ /**
++ * Waits until all threads in this pool have shutdown, or until the specified time has passed.
++ * @param msToWait Maximum time to wait.
++ * @return {@code false} if the maximum time passed, {@code true} otherwise.
++ */
++ public boolean join(final long msToWait) {
++ try {
++ return this.join(msToWait, false);
++ } catch (final InterruptedException ex) {
++ throw new IllegalStateException(ex);
++ }
++ }
++
++ /**
++ * Waits until all threads in this pool have shutdown, or until the specified time has passed.
++ * @param msToWait Maximum time to wait.
++ * @return {@code false} if the maximum time passed, {@code true} otherwise.
++ * @throws InterruptedException If this thread is interrupted.
++ */
++ public boolean joinInterruptable(final long msToWait) throws InterruptedException {
++ return this.join(msToWait, true);
++ }
++
++ protected final boolean join(final long msToWait, final boolean interruptable) throws InterruptedException {
++ final long nsToWait = msToWait * (1000 * 1000);
++ final long start = System.nanoTime();
++ final long deadline = start + nsToWait;
++ boolean interrupted = false;
++ try {
++ for (final PrioritisedThread thread : this.threads) {
++ for (;;) {
++ if (!thread.isAlive()) {
++ break;
++ }
++ final long current = System.nanoTime();
++ if (current >= deadline) {
++ return false;
++ }
++
++ try {
++ thread.join(Math.max(1L, (deadline - current) / (1000 * 1000)));
++ } catch (final InterruptedException ex) {
++ if (interruptable) {
++ throw ex;
++ }
++ interrupted = true;
++ }
++ }
++ }
++
++ return true;
++ } finally {
++ if (interrupted) {
++ Thread.currentThread().interrupt();
++ }
++ }
++ }
++
++ public void shutdown(final boolean wait) {
++ final ArrayList<PrioritisedPoolExecutorImpl> queuesToShutdown;
++ synchronized (this.nonShutdownQueues) {
++ this.shutdown = true;
++ queuesToShutdown = new ArrayList<>(this.nonShutdownQueues);
++ }
++
++ for (final PrioritisedPoolExecutorImpl queue : queuesToShutdown) {
++ queue.shutdown();
++ }
++
++ for (final PrioritisedThread thread : this.threads) {
++ // none of these can be true or else NPE
++ thread.close(false, false);
++ }
++
++ if (wait) {
++ final ArrayList<PrioritisedPoolExecutorImpl> queues;
++ synchronized (this.activeQueues) {
++ queues = new ArrayList<>(this.activeQueues);
++ }
++ for (final PrioritisedPoolExecutorImpl queue : queues) {
++ queue.waitUntilAllExecuted();
++ }
++ }
++ }
++
++ protected static final class PrioritisedThread extends PrioritisedQueueExecutorThread {
++
++ protected final PrioritisedThreadPool pool;
++ protected final AtomicBoolean alertedHighPriority = new AtomicBoolean();
++
++ public PrioritisedThread(final PrioritisedThreadPool pool) {
++ super(null);
++ this.pool = pool;
++ }
++
++ public boolean alertHighPriorityExecutor() {
++ if (!this.notifyTasks()) {
++ if (!this.alertedHighPriority.get()) {
++ this.alertedHighPriority.set(true);
++ }
++ return false;
++ }
++
++ return true;
++ }
++
++ private boolean isAlertedHighPriority() {
++ return this.alertedHighPriority.get() && this.alertedHighPriority.getAndSet(false);
++ }
++
++ @Override
++ protected boolean pollTasks() {
++ final PrioritisedThreadPool pool = this.pool;
++ final TreeSet<PrioritisedPoolExecutorImpl> queues = this.pool.queues;
++
++ boolean ret = false;
++ for (;;) {
++ if (this.halted) {
++ break;
++ }
++ // try to find a queue
++ // note that if and ONLY IF the queues set is empty, this means there are no tasks for us to execute.
++ // so we can only break when it's empty
++ final PrioritisedPoolExecutorImpl queue;
++ // select queue
++ synchronized (queues) {
++ queue = queues.pollFirst();
++ if (queue == null) {
++ // no tasks to execute
++ break;
++ }
++
++ queue.schedulingId = ++pool.schedulingIdGenerator;
++ // we own this queue now, so increment the executor count
++ // do we also need to push this queue up for grabs for another executor?
++ if (++queue.concurrentExecutors < queue.maximumExecutors) {
++ // re-add to queues
++ // it's very important this is done in the same synchronised block for polling, as this prevents
++ // us from possibly later adding a queue that should not exist in the set
++ queues.add(queue);
++ queue.isQueued = true;
++ } else {
++ queue.isQueued = false;
++ }
++ // note: we cannot drain entries from the queue while holding this lock, as it will cause deadlock
++ // the queue addition holds the per-queue lock first then acquires the lock we have now, but if we
++ // try to poll now we don't hold the per queue lock but we do hold the global lock...
++ }
++
++ // parse tasks as long as we are allowed
++ final long start = System.nanoTime();
++ final long deadline = start + pool.queueMaxHoldTime;
++ do {
++ try {
++ if (this.halted) {
++ break;
++ }
++ if (!queue.executeTask()) {
++ // no more tasks, try next queue
++ break;
++ }
++ ret = true;
++ } catch (final ThreadDeath death) {
++ throw death; // goodbye world...
++ } catch (final Throwable throwable) {
++ LOGGER.error("Exception thrown from thread '" + this.getName() + "' in queue '" + queue.toString() + "'", throwable);
++ }
++ } while (!this.isAlertedHighPriority() && System.nanoTime() <= deadline);
++
++ synchronized (queues) {
++ // decrement executors, we are no longer executing
++ if (queue.isQueued) {
++ queues.remove(queue);
++ queue.isQueued = false;
++ }
++ if (--queue.concurrentExecutors == 0 && queue.scheduledPriority == null) {
++ // reset scheduling id once the queue is empty again
++ // this will ensure empty queues are not prioritised suddenly over active queues once tasks are
++ // queued
++ queue.schedulingId = 0L;
++ }
++
++ // ensure the executor is queued for execution again
++ if (!queue.isHalted && queue.scheduledPriority != null) { // make sure it actually has tasks
++ queues.add(queue);
++ queue.isQueued = true;
++ }
++ }
++ }
++
++ return ret;
++ }
++ }
++
++ public interface PrioritisedPoolExecutor extends PrioritisedExecutor {
++
++ /**
++ * Removes this queue from the thread pool without shutting the queue down or waiting for queued tasks to be executed
++ */
++ public void halt();
++
++ /**
++ * Returns whether this executor is scheduled to run tasks or is running tasks, otherwise it returns whether
++ * this queue is not halted and not shutdown.
++ */
++ public boolean isActive();
++ }
++
++ protected static final class PrioritisedPoolExecutorImpl extends PrioritisedThreadedTaskQueue implements PrioritisedPoolExecutor {
++
++ protected final PrioritisedThreadPool pool;
++ protected final long[] priorityCounts = new long[Priority.TOTAL_SCHEDULABLE_PRIORITIES];
++ protected long schedulingId;
++ protected int concurrentExecutors;
++ protected Priority scheduledPriority;
++
++ protected final String name;
++ protected final int maximumExecutors;
++ protected boolean isQueued;
++
++ public PrioritisedPoolExecutorImpl(final PrioritisedThreadPool pool, final String name, final int maximumExecutors) {
++ this.pool = pool;
++ this.name = name;
++ this.maximumExecutors = maximumExecutors;
++ }
++
++ public static Comparator<PrioritisedPoolExecutorImpl> comparator() {
++ return (final PrioritisedPoolExecutorImpl p1, final PrioritisedPoolExecutorImpl p2) -> {
++ if (p1 == p2) {
++ return 0;
++ }
++
++ // prefer higher priority
++ final int priorityCompare = p1.scheduledPriority.ordinal() - p2.scheduledPriority.ordinal();
++ if (priorityCompare != 0) {
++ return priorityCompare;
++ }
++
++ // try to spread out the executors so that each can have threads executing
++ final int executorCompare = p1.concurrentExecutors - p2.concurrentExecutors;
++ if (executorCompare != 0) {
++ return executorCompare;
++ }
++
++ // if all else fails here we just choose whichever executor was queued first
++ return Long.compare(p1.schedulingId, p2.schedulingId);
++ };
++ }
++
++ private boolean isHalted;
++
++ @Override
++ public void halt() {
++ final PrioritisedThreadPool pool = this.pool;
++ final TreeSet<PrioritisedPoolExecutorImpl> queues = pool.queues;
++ synchronized (queues) {
++ if (this.isHalted) {
++ return;
++ }
++ this.isHalted = true;
++ if (this.isQueued) {
++ queues.remove(this);
++ this.isQueued = false;
++ }
++ }
++ synchronized (pool.nonShutdownQueues) {
++ pool.nonShutdownQueues.remove(this);
++ }
++ synchronized (pool.activeQueues) {
++ pool.activeQueues.remove(this);
++ }
++ }
++
++ @Override
++ public boolean isActive() {
++ final PrioritisedThreadPool pool = this.pool;
++ final TreeSet<PrioritisedPoolExecutorImpl> queues = pool.queues;
++
++ synchronized (queues) {
++ if (this.concurrentExecutors != 0) {
++ return true;
++ }
++ synchronized (pool.activeQueues) {
++ if (pool.activeQueues.contains(this)) {
++ return true;
++ }
++ }
++ }
++
++ return false;
++ }
++
++ private long totalQueuedTasks = 0L;
++
++ @Override
++ protected void priorityChange(final PrioritisedThreadedTaskQueue.PrioritisedTask task, final Priority from, final Priority to) {
++ // Note: The superclass' queue lock is ALWAYS held when inside this method. So we do NOT need to do any additional synchronisation
++ // for accessing this queue's state.
++ final long[] priorityCounts = this.priorityCounts;
++ final boolean shutdown = this.isShutdown();
++
++ if (from == null && to == Priority.COMPLETING) {
++ throw new IllegalStateException("Cannot complete task without queueing it first");
++ }
++
++ // we should only notify for queueing of tasks, not changing priorities
++ final boolean shouldNotifyTasks = from == null;
++
++ final Priority scheduledPriority = this.scheduledPriority;
++ if (from != null) {
++ --priorityCounts[from.priority];
++ }
++ if (to != Priority.COMPLETING) {
++ ++priorityCounts[to.priority];
++ }
++ final long totalQueuedTasks;
++ if (to == Priority.COMPLETING) {
++ totalQueuedTasks = --this.totalQueuedTasks;
++ } else if (from == null) {
++ totalQueuedTasks = ++this.totalQueuedTasks;
++ } else {
++ totalQueuedTasks = this.totalQueuedTasks;
++ }
++
++ // find new highest priority
++ int highest = Math.min(to == Priority.COMPLETING ? Priority.IDLE.priority : to.priority, scheduledPriority == null ? Priority.IDLE.priority : scheduledPriority.priority);
++ int lowestPriority = priorityCounts.length; // exclusive
++ for (;highest < lowestPriority; ++highest) {
++ final long count = priorityCounts[highest];
++ if (count < 0) {
++ throw new IllegalStateException("Priority " + highest + " has " + count + " scheduled tasks");
++ }
++
++ if (count != 0) {
++ break;
++ }
++ }
++
++ final Priority newPriority;
++ if (highest == lowestPriority) {
++ // no tasks left
++ newPriority = null;
++ } else if (shutdown) {
++ // whichever is lower, the actual greatest priority or simply HIGHEST
++ // this is so shutdown automatically gets priority
++ newPriority = Priority.getPriority(Math.min(highest, Priority.HIGHEST.priority));
++ } else {
++ newPriority = Priority.getPriority(highest);
++ }
++
++ final int executorsWanted;
++ boolean shouldNotifyHighPriority = false;
++
++ final PrioritisedThreadPool pool = this.pool;
++ final TreeSet<PrioritisedPoolExecutorImpl> queues = pool.queues;
++
++ synchronized (queues) {
++ if (!this.isQueued) {
++ // see if we need to be queued
++ if (newPriority != null) {
++ if (this.schedulingId == 0L) {
++ this.schedulingId = ++pool.schedulingIdGenerator;
++ }
++ this.scheduledPriority = newPriority; // must be updated before queue add
++ if (!this.isHalted && this.concurrentExecutors < this.maximumExecutors) {
++ shouldNotifyHighPriority = newPriority.isHigherOrEqualPriority(Priority.HIGH);
++ queues.add(this);
++ this.isQueued = true;
++ }
++ } else {
++ // do not queue
++ this.scheduledPriority = null;
++ }
++ } else {
++ // see if we need to NOT be queued
++ if (newPriority == null) {
++ queues.remove(this);
++ this.scheduledPriority = null;
++ this.isQueued = false;
++ } else if (scheduledPriority != newPriority) {
++ // if our priority changed, we need to update it - which means removing and re-adding into the queue
++ queues.remove(this);
++ // only now can we update scheduledPriority, since we are no longer in queue
++ this.scheduledPriority = newPriority;
++ queues.add(this);
++ shouldNotifyHighPriority = (scheduledPriority == null || scheduledPriority.isLowerPriority(Priority.HIGH)) && newPriority.isHigherOrEqualPriority(Priority.HIGH);
++ }
++ }
++
++ if (this.isQueued) {
++ executorsWanted = Math.min(this.maximumExecutors - this.concurrentExecutors, (int)totalQueuedTasks);
++ } else {
++ executorsWanted = 0;
++ }
++ }
++
++ if (newPriority == null && shutdown) {
++ synchronized (pool.activeQueues) {
++ pool.activeQueues.remove(this);
++ }
++ }
++
++ // Wake up the number of executors we want
++ if (executorsWanted > 0 || (shouldNotifyTasks | shouldNotifyHighPriority)) {
++ int notified = 0;
++ for (final PrioritisedThread thread : pool.threads) {
++ if ((shouldNotifyHighPriority ? thread.alertHighPriorityExecutor() : thread.notifyTasks())
++ && (++notified >= executorsWanted)) {
++ break;
++ }
++ }
++ }
++ }
++
++ @Override
++ public boolean shutdown() {
++ final boolean ret = super.shutdown();
++ if (!ret) {
++ return ret;
++ }
++
++ final PrioritisedThreadPool pool = this.pool;
++
++ // remove from active queues
++ synchronized (pool.nonShutdownQueues) {
++ pool.nonShutdownQueues.remove(this);
++ }
++
++ final TreeSet<PrioritisedPoolExecutorImpl> queues = pool.queues;
++
++ // try and shift around our priority
++ synchronized (queues) {
++ if (this.scheduledPriority == null) {
++ // no tasks are queued, ensure we aren't in activeQueues
++ synchronized (pool.activeQueues) {
++ pool.activeQueues.remove(this);
++ }
++
++ return ret;
++ }
++
++ // try to set scheduled priority to HIGHEST so it drains faster
++
++ if (this.scheduledPriority.isHigherOrEqualPriority(Priority.HIGHEST)) {
++ // already at target priority (highest or above)
++ return ret;
++ }
++
++ // shift priority to HIGHEST
++
++ if (this.isQueued) {
++ queues.remove(this);
++ this.scheduledPriority = Priority.HIGHEST;
++ queues.add(this);
++ } else {
++ this.scheduledPriority = Priority.HIGHEST;
++ }
++ }
++
++ return ret;
++ }
++ }
++}
+diff --git a/src/main/java/ca/spottedleaf/concurrentutil/executor/standard/PrioritisedThreadedTaskQueue.java b/src/main/java/ca/spottedleaf/concurrentutil/executor/standard/PrioritisedThreadedTaskQueue.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..b71404be2c82f7db35272b367af861e94d6c73d3
+--- /dev/null
++++ b/src/main/java/ca/spottedleaf/concurrentutil/executor/standard/PrioritisedThreadedTaskQueue.java
+@@ -0,0 +1,378 @@
++package ca.spottedleaf.concurrentutil.executor.standard;
++
++import java.util.ArrayDeque;
++import java.util.concurrent.atomic.AtomicLong;
++
++public class PrioritisedThreadedTaskQueue implements PrioritisedExecutor {
++
++ protected final ArrayDeque<PrioritisedTask>[] queues = new ArrayDeque[Priority.TOTAL_SCHEDULABLE_PRIORITIES]; {
++ for (int i = 0; i < Priority.TOTAL_SCHEDULABLE_PRIORITIES; ++i) {
++ this.queues[i] = new ArrayDeque<>();
++ }
++ }
++
++ // Use AtomicLong to separate from the queue field, we don't want false sharing here.
++ protected final AtomicLong totalScheduledTasks = new AtomicLong();
++ protected final AtomicLong totalCompletedTasks = new AtomicLong();
++
++ // this is here to prevent failures to queue stalling flush() calls (as the schedule calls would increment totalScheduledTasks without this check)
++ protected volatile boolean hasShutdown;
++
++ protected long taskIdGenerator = 0;
++
++ @Override
++ public PrioritisedExecutor.PrioritisedTask queueRunnable(final Runnable task, final PrioritisedExecutor.Priority priority) throws IllegalStateException, IllegalArgumentException {
++ if (!PrioritisedExecutor.Priority.isValidPriority(priority)) {
++ throw new IllegalArgumentException("Priority " + priority + " is invalid");
++ }
++ if (task == null) {
++ throw new NullPointerException("Task cannot be null");
++ }
++
++ if (this.hasShutdown) {
++ // prevent us from stalling flush() calls by incrementing scheduled tasks when we really didn't schedule something
++ throw new IllegalStateException("Queue has shutdown");
++ }
++
++ final PrioritisedTask ret;
++
++ synchronized (this.queues) {
++ if (this.hasShutdown) {
++ throw new IllegalStateException("Queue has shutdown");
++ }
++ this.getAndAddTotalScheduledTasksVolatile(1L);
++
++ ret = new PrioritisedTask(this.taskIdGenerator++, task, priority, this);
++
++ this.queues[ret.priority.priority].add(ret);
++
++ // call priority change callback (note: only after we successfully queue!)
++ this.priorityChange(ret, null, priority);
++ }
++
++ return ret;
++ }
++
++ @Override
++ public PrioritisedExecutor.PrioritisedTask createTask(final Runnable task, final Priority priority) {
++ if (!PrioritisedExecutor.Priority.isValidPriority(priority)) {
++ throw new IllegalArgumentException("Priority " + priority + " is invalid");
++ }
++ if (task == null) {
++ throw new NullPointerException("Task cannot be null");
++ }
++
++ return new PrioritisedTask(task, priority, this);
++ }
++
++ @Override
++ public long getTotalTasksScheduled() {
++ return this.totalScheduledTasks.get();
++ }
++
++ @Override
++ public long getTotalTasksExecuted() {
++ return this.totalCompletedTasks.get();
++ }
++
++ // callback method for subclasses to override
++ // from is null when a task is immediately created
++ protected void priorityChange(final PrioritisedTask task, final Priority from, final Priority to) {}
++
++ /**
++ * Polls the highest priority task currently available. {@code null} if none. This will mark the
++ * returned task as completed.
++ */
++ protected PrioritisedTask poll() {
++ return this.poll(Priority.IDLE);
++ }
++
++ protected PrioritisedTask poll(final PrioritisedExecutor.Priority minPriority) {
++ final ArrayDeque<PrioritisedTask>[] queues = this.queues;
++ synchronized (queues) {
++ final int max = minPriority.priority;
++ for (int i = 0; i <= max; ++i) {
++ final ArrayDeque<PrioritisedTask> queue = queues[i];
++ PrioritisedTask task;
++ while ((task = queue.pollFirst()) != null) {
++ if (task.trySetCompleting(i)) {
++ return task;
++ }
++ }
++ }
++ }
++
++ return null;
++ }
++
++ /**
++ * Polls and executes the highest priority task currently available. Exceptions thrown during task execution will
++ * be rethrown.
++ * @return {@code true} if a task was executed, {@code false} otherwise.
++ */
++ @Override
++ public boolean executeTask() {
++ final PrioritisedTask task = this.poll();
++
++ if (task != null) {
++ task.executeInternal();
++ return true;
++ }
++
++ return false;
++ }
++
++ @Override
++ public boolean shutdown() {
++ synchronized (this.queues) {
++ if (this.hasShutdown) {
++ return false;
++ }
++ this.hasShutdown = true;
++ }
++ return true;
++ }
++
++ @Override
++ public boolean isShutdown() {
++ return this.hasShutdown;
++ }
++
++ /* totalScheduledTasks */
++
++ protected final long getTotalScheduledTasksVolatile() {
++ return this.totalScheduledTasks.get();
++ }
++
++ protected final long getAndAddTotalScheduledTasksVolatile(final long value) {
++ return this.totalScheduledTasks.getAndAdd(value);
++ }
++
++ /* totalCompletedTasks */
++
++ protected final long getTotalCompletedTasksVolatile() {
++ return this.totalCompletedTasks.get();
++ }
++
++ protected final long getAndAddTotalCompletedTasksVolatile(final long value) {
++ return this.totalCompletedTasks.getAndAdd(value);
++ }
++
++ protected static final class PrioritisedTask implements PrioritisedExecutor.PrioritisedTask {
++ protected final PrioritisedThreadedTaskQueue queue;
++ protected long id;
++ protected static final long NOT_SCHEDULED_ID = -1L;
++
++ protected Runnable runnable;
++ protected volatile PrioritisedExecutor.Priority priority;
++
++ protected PrioritisedTask(final long id, final Runnable runnable, final PrioritisedExecutor.Priority priority, final PrioritisedThreadedTaskQueue queue) {
++ if (!PrioritisedExecutor.Priority.isValidPriority(priority)) {
++ throw new IllegalArgumentException("Invalid priority " + priority);
++ }
++
++ this.priority = priority;
++ this.runnable = runnable;
++ this.queue = queue;
++ this.id = id;
++ }
++
++ protected PrioritisedTask(final Runnable runnable, final PrioritisedExecutor.Priority priority, final PrioritisedThreadedTaskQueue queue) {
++ if (!PrioritisedExecutor.Priority.isValidPriority(priority)) {
++ throw new IllegalArgumentException("Invalid priority " + priority);
++ }
++
++ this.priority = priority;
++ this.runnable = runnable;
++ this.queue = queue;
++ this.id = NOT_SCHEDULED_ID;
++ }
++
++ @Override
++ public boolean queue() {
++ if (this.queue.hasShutdown) {
++ throw new IllegalStateException("Queue has shutdown");
++ }
++
++ synchronized (this.queue.queues) {
++ if (this.queue.hasShutdown) {
++ throw new IllegalStateException("Queue has shutdown");
++ }
++
++ final PrioritisedExecutor.Priority priority = this.priority;
++ if (priority == PrioritisedExecutor.Priority.COMPLETING) {
++ return false;
++ }
++
++ if (this.id != NOT_SCHEDULED_ID) {
++ return false;
++ }
++
++ this.queue.getAndAddTotalScheduledTasksVolatile(1L);
++ this.id = this.queue.taskIdGenerator++;
++ this.queue.queues[priority.priority].add(this);
++
++ this.queue.priorityChange(this, null, priority);
++
++ return true;
++ }
++ }
++
++ protected boolean trySetCompleting(final int minPriority) {
++ final PrioritisedExecutor.Priority oldPriority = this.priority;
++ if (oldPriority != PrioritisedExecutor.Priority.COMPLETING && oldPriority.isHigherOrEqualPriority(minPriority)) {
++ this.priority = PrioritisedExecutor.Priority.COMPLETING;
++ if (this.id != NOT_SCHEDULED_ID) {
++ this.queue.priorityChange(this, oldPriority, PrioritisedExecutor.Priority.COMPLETING);
++ }
++ return true;
++ }
++
++ return false;
++ }
++
++ @Override
++ public PrioritisedExecutor.Priority getPriority() {
++ return this.priority;
++ }
++
++ @Override
++ public boolean setPriority(final PrioritisedExecutor.Priority priority) {
++ if (!PrioritisedExecutor.Priority.isValidPriority(priority)) {
++ throw new IllegalArgumentException("Invalid priority " + priority);
++ }
++ synchronized (this.queue.queues) {
++ final PrioritisedExecutor.Priority curr = this.priority;
++
++ if (curr == PrioritisedExecutor.Priority.COMPLETING) {
++ return false;
++ }
++
++ if (curr == priority) {
++ return true;
++ }
++
++ this.priority = priority;
++ if (this.id != NOT_SCHEDULED_ID) {
++ this.queue.queues[priority.priority].add(this);
++
++ // call priority change callback
++ this.queue.priorityChange(this, curr, priority);
++ }
++ }
++
++ return true;
++ }
++
++ @Override
++ public boolean raisePriority(final PrioritisedExecutor.Priority priority) {
++ if (!PrioritisedExecutor.Priority.isValidPriority(priority)) {
++ throw new IllegalArgumentException("Invalid priority " + priority);
++ }
++
++ synchronized (this.queue.queues) {
++ final PrioritisedExecutor.Priority curr = this.priority;
++
++ if (curr == PrioritisedExecutor.Priority.COMPLETING) {
++ return false;
++ }
++
++ if (curr.isHigherOrEqualPriority(priority)) {
++ return true;
++ }
++
++ this.priority = priority;
++ if (this.id != NOT_SCHEDULED_ID) {
++ this.queue.queues[priority.priority].add(this);
++
++ // call priority change callback
++ this.queue.priorityChange(this, curr, priority);
++ }
++ }
++
++ return true;
++ }
++
++ @Override
++ public boolean lowerPriority(final PrioritisedExecutor.Priority priority) {
++ if (!PrioritisedExecutor.Priority.isValidPriority(priority)) {
++ throw new IllegalArgumentException("Invalid priority " + priority);
++ }
++
++ synchronized (this.queue.queues) {
++ final PrioritisedExecutor.Priority curr = this.priority;
++
++ if (curr == PrioritisedExecutor.Priority.COMPLETING) {
++ return false;
++ }
++
++ if (curr.isLowerOrEqualPriority(priority)) {
++ return true;
++ }
++
++ this.priority = priority;
++ if (this.id != NOT_SCHEDULED_ID) {
++ this.queue.queues[priority.priority].add(this);
++
++ // call priority change callback
++ this.queue.priorityChange(this, curr, priority);
++ }
++ }
++
++ return true;
++ }
++
++ @Override
++ public boolean cancel() {
++ final long id;
++ synchronized (this.queue.queues) {
++ final Priority oldPriority = this.priority;
++ if (oldPriority == PrioritisedExecutor.Priority.COMPLETING) {
++ return false;
++ }
++
++ this.priority = PrioritisedExecutor.Priority.COMPLETING;
++ // call priority change callback
++ if ((id = this.id) != NOT_SCHEDULED_ID) {
++ this.queue.priorityChange(this, oldPriority, PrioritisedExecutor.Priority.COMPLETING);
++ }
++ }
++ this.runnable = null;
++ if (id != NOT_SCHEDULED_ID) {
++ this.queue.getAndAddTotalCompletedTasksVolatile(1L);
++ }
++ return true;
++ }
++
++ protected void executeInternal() {
++ try {
++ final Runnable execute = this.runnable;
++ this.runnable = null;
++ execute.run();
++ } finally {
++ if (this.id != NOT_SCHEDULED_ID) {
++ this.queue.getAndAddTotalCompletedTasksVolatile(1L);
++ }
++ }
++ }
++
++ @Override
++ public boolean execute() {
++ synchronized (this.queue.queues) {
++ final Priority oldPriority = this.priority;
++ if (oldPriority == PrioritisedExecutor.Priority.COMPLETING) {
++ return false;
++ }
++
++ this.priority = PrioritisedExecutor.Priority.COMPLETING;
++ // call priority change callback
++ if (this.id != NOT_SCHEDULED_ID) {
++ this.queue.priorityChange(this, oldPriority, PrioritisedExecutor.Priority.COMPLETING);
++ }
++ }
++
++ this.executeInternal();
++ return true;
++ }
++ }
++}
+diff --git a/src/main/java/ca/spottedleaf/concurrentutil/map/SWMRHashTable.java b/src/main/java/ca/spottedleaf/concurrentutil/map/SWMRHashTable.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..a037bb57bedc0cde6b979f5c1f9669678fa7bd16
+--- /dev/null
++++ b/src/main/java/ca/spottedleaf/concurrentutil/map/SWMRHashTable.java
+@@ -0,0 +1,1673 @@
++package ca.spottedleaf.concurrentutil.map;
++
++import ca.spottedleaf.concurrentutil.util.ArrayUtil;
++import ca.spottedleaf.concurrentutil.util.CollectionUtil;
++import ca.spottedleaf.concurrentutil.util.ConcurrentUtil;
++import ca.spottedleaf.concurrentutil.util.Validate;
++import io.papermc.paper.util.IntegerUtil;
++import java.lang.invoke.VarHandle;
++import java.util.ArrayList;
++import java.util.Arrays;
++import java.util.Collection;
++import java.util.Iterator;
++import java.util.List;
++import java.util.Map;
++import java.util.NoSuchElementException;
++import java.util.Set;
++import java.util.Spliterator;
++import java.util.Spliterators;
++import java.util.function.BiConsumer;
++import java.util.function.BiFunction;
++import java.util.function.BiPredicate;
++import java.util.function.Consumer;
++import java.util.function.Function;
++import java.util.function.IntFunction;
++import java.util.function.Predicate;
++
++/**
++ * <p>
++ * Note: Not really tested, use at your own risk.
++ * </p>
++ * This map is safe for reading from multiple threads, however it is only safe to write from a single thread.
++ * {@code null} keys or values are not permitted. Writes to values in this map are guaranteed to be ordered by release semantics,
++ * however immediate visibility to other threads is not guaranteed. However, writes are guaranteed to be made visible eventually.
++ * Reads are ordered by acquire semantics.
++ * <p>
++ * Iterators cannot be modified concurrently, and its backing map cannot be modified concurrently. There is no
++ * fast-fail attempt made by iterators, thus modifying the iterator's backing map while iterating will have undefined
++ * behaviour.
++ * </p>
++ * <p>
++ * Subclasses should override {@link #clone()} to return correct instances of this class.
++ * </p>
++ * @param <K> {@inheritDoc}
++ * @param <V> {@inheritDoc}
++ */
++public class SWMRHashTable<K, V> implements Map<K, V>, Iterable<Map.Entry<K, V>> {
++
++ protected int size;
++
++ protected TableEntry<K, V>[] table;
++
++ protected final float loadFactor;
++
++ protected static final VarHandle SIZE_HANDLE = ConcurrentUtil.getVarHandle(SWMRHashTable.class, "size", int.class);
++ protected static final VarHandle TABLE_HANDLE = ConcurrentUtil.getVarHandle(SWMRHashTable.class, "table", TableEntry[].class);
++
++ /* size */
++
++ protected final int getSizePlain() {
++ return (int)SIZE_HANDLE.get(this);
++ }
++
++ protected final int getSizeOpaque() {
++ return (int)SIZE_HANDLE.getOpaque(this);
++ }
++
++ protected final int getSizeAcquire() {
++ return (int)SIZE_HANDLE.getAcquire(this);
++ }
++
++ protected final void setSizePlain(final int value) {
++ SIZE_HANDLE.set(this, value);
++ }
++
++ protected final void setSizeOpaque(final int value) {
++ SIZE_HANDLE.setOpaque(this, value);
++ }
++
++ protected final void setSizeRelease(final int value) {
++ SIZE_HANDLE.setRelease(this, value);
++ }
++
++ /* table */
++
++ protected final TableEntry<K, V>[] getTablePlain() {
++ //noinspection unchecked
++ return (TableEntry<K, V>[])TABLE_HANDLE.get(this);
++ }
++
++ protected final TableEntry<K, V>[] getTableAcquire() {
++ //noinspection unchecked
++ return (TableEntry<K, V>[])TABLE_HANDLE.getAcquire(this);
++ }
++
++ protected final void setTablePlain(final TableEntry<K, V>[] table) {
++ TABLE_HANDLE.set(this, table);
++ }
++
++ protected final void setTableRelease(final TableEntry<K, V>[] table) {
++ TABLE_HANDLE.setRelease(this, table);
++ }
++
++ protected static final int DEFAULT_CAPACITY = 16;
++ protected static final float DEFAULT_LOAD_FACTOR = 0.75f;
++ protected static final int MAXIMUM_CAPACITY = Integer.MIN_VALUE >>> 1;
++
++ /**
++ * Constructs this map with a capacity of {@code 16} and load factor of {@code 0.75f}.
++ */
++ public SWMRHashTable() {
++ this(DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR);
++ }
++
++ /**
++ * Constructs this map with the specified capacity and load factor of {@code 0.75f}.
++ * @param capacity specified initial capacity, > 0
++ */
++ public SWMRHashTable(final int capacity) {
++ this(capacity, DEFAULT_LOAD_FACTOR);
++ }
++
++ /**
++ * Constructs this map with the specified capacity and load factor.
++ * @param capacity specified capacity, > 0
++ * @param loadFactor specified load factor, > 0 && finite
++ */
++ public SWMRHashTable(final int capacity, final float loadFactor) {
++ final int tableSize = getCapacityFor(capacity);
++
++ if (loadFactor <= 0.0 || !Float.isFinite(loadFactor)) {
++ throw new IllegalArgumentException("Invalid load factor: " + loadFactor);
++ }
++
++ //noinspection unchecked
++ final TableEntry<K, V>[] table = new TableEntry[tableSize];
++ this.setTablePlain(table);
++
++ if (tableSize == MAXIMUM_CAPACITY) {
++ this.threshold = -1;
++ } else {
++ this.threshold = getTargetCapacity(tableSize, loadFactor);
++ }
++
++ this.loadFactor = loadFactor;
++ }
++
++ /**
++ * Constructs this map with a capacity of {@code 16} or the specified map's size, whichever is larger, and
++ * with a load factor of {@code 0.75f}.
++ * All of the specified map's entries are copied into this map.
++ * @param other The specified map.
++ */
++ public SWMRHashTable(final Map<K, V> other) {
++ this(DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR, other);
++ }
++
++ /**
++ * Constructs this map with a minimum capacity of the specified capacity or the specified map's size, whichever is larger, and
++ * with a load factor of {@code 0.75f}.
++ * All of the specified map's entries are copied into this map.
++ * @param capacity specified capacity, > 0
++ * @param other The specified map.
++ */
++ public SWMRHashTable(final int capacity, final Map<K, V> other) {
++ this(capacity, DEFAULT_LOAD_FACTOR, other);
++ }
++
++ /**
++ * Constructs this map with a min capacity of the specified capacity or the specified map's size, whichever is larger, and
++ * with the specified load factor.
++ * All of the specified map's entries are copied into this map.
++ * @param capacity specified capacity, > 0
++ * @param loadFactor specified load factor, > 0 && finite
++ * @param other The specified map.
++ */
++ public SWMRHashTable(final int capacity, final float loadFactor, final Map<K, V> other) {
++ this(Math.max(Validate.notNull(other, "Null map").size(), capacity), loadFactor);
++ this.putAll(other);
++ }
++
++ public final float getLoadFactor() {
++ return this.loadFactor;
++ }
++
++ protected static int getCapacityFor(final int capacity) {
++ if (capacity <= 0) {
++ throw new IllegalArgumentException("Invalid capacity: " + capacity);
++ }
++ if (capacity >= MAXIMUM_CAPACITY) {
++ return MAXIMUM_CAPACITY;
++ }
++ return IntegerUtil.roundCeilLog2(capacity);
++ }
++
++ /** Callers must still use acquire when reading the value of the entry. */
++ protected final TableEntry<K, V> getEntryForOpaque(final K key) {
++ final int hash = SWMRHashTable.getHash(key);
++ final TableEntry<K, V>[] table = this.getTableAcquire();
++
++ for (TableEntry<K, V> curr = ArrayUtil.getOpaque(table, hash & (table.length - 1)); curr != null; curr = curr.getNextOpaque()) {
++ if (hash == curr.hash && (key == curr.key || curr.key.equals(key))) {
++ return curr;
++ }
++ }
++
++ return null;
++ }
++
++ protected final TableEntry<K, V> getEntryForPlain(final K key) {
++ final int hash = SWMRHashTable.getHash(key);
++ final TableEntry<K, V>[] table = this.getTablePlain();
++
++ for (TableEntry<K, V> curr = table[hash & (table.length - 1)]; curr != null; curr = curr.getNextPlain()) {
++ if (hash == curr.hash && (key == curr.key || curr.key.equals(key))) {
++ return curr;
++ }
++ }
++
++ return null;
++ }
++
++ /* MT-Safe */
++
++ /** must be deterministic given a key */
++ private static int getHash(final Object key) {
++ int hash = key == null ? 0 : key.hashCode();
++ // inlined IntegerUtil#hash0
++ hash *= 0x36935555;
++ hash ^= hash >>> 16;
++ return hash;
++ }
++
++ static final int HASH_BITS = 0x7fffffff; // usable bits of normal node hash
++ static final int spread(int h) {
++ return (h ^ (h >>> 16)) & HASH_BITS;
++ }
++
++ // rets -1 if capacity*loadFactor is too large
++ protected static int getTargetCapacity(final int capacity, final float loadFactor) {
++ final double ret = (double)capacity * (double)loadFactor;
++ if (Double.isInfinite(ret) || ret >= ((double)Integer.MAX_VALUE)) {
++ return -1;
++ }
++
++ return (int)ret;
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public boolean equals(final Object obj) {
++ if (this == obj) {
++ return true;
++ }
++ /* Make no attempt to deal with concurrent modifications */
++ if (!(obj instanceof Map)) {
++ return false;
++ }
++ final Map<?, ?> other = (Map<?, ?>)obj;
++
++ if (this.size() != other.size()) {
++ return false;
++ }
++
++ final TableEntry<K, V>[] table = this.getTableAcquire();
++
++ for (int i = 0, len = table.length; i < len; ++i) {
++ for (TableEntry<K, V> curr = ArrayUtil.getOpaque(table, i); curr != null; curr = curr.getNextOpaque()) {
++ final V value = curr.getValueAcquire();
++
++ final Object otherValue = other.get(curr.key);
++ if (otherValue == null || (value != otherValue && value.equals(otherValue))) {
++ return false;
++ }
++ }
++ }
++
++ return true;
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public int hashCode() {
++ /* Make no attempt to deal with concurrent modifications */
++ int hash = 0;
++ final TableEntry<K, V>[] table = this.getTableAcquire();
++
++ for (int i = 0, len = table.length; i < len; ++i) {
++ for (TableEntry<K, V> curr = ArrayUtil.getOpaque(table, i); curr != null; curr = curr.getNextOpaque()) {
++ hash += curr.hashCode();
++ }
++ }
++
++ return hash;
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public String toString() {
++ final StringBuilder builder = new StringBuilder(64);
++ builder.append("SingleWriterMultiReaderHashMap:{");
++
++ this.forEach((final K key, final V value) -> {
++ builder.append("{key: \"").append(key).append("\", value: \"").append(value).append("\"}");
++ });
++
++ return builder.append('}').toString();
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public SWMRHashTable<K, V> clone() {
++ return new SWMRHashTable<>(this.getTableAcquire().length, this.loadFactor, this);
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public Iterator<Entry<K, V>> iterator() {
++ return new EntryIterator<>(this.getTableAcquire(), this);
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public void forEach(final Consumer<? super Entry<K, V>> action) {
++ Validate.notNull(action, "Null action");
++
++ final TableEntry<K, V>[] table = this.getTableAcquire();
++ for (int i = 0, len = table.length; i < len; ++i) {
++ for (TableEntry<K, V> curr = ArrayUtil.getOpaque(table, i); curr != null; curr = curr.getNextOpaque()) {
++ action.accept(curr);
++ }
++ }
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public void forEach(final BiConsumer<? super K, ? super V> action) {
++ Validate.notNull(action, "Null action");
++
++ final TableEntry<K, V>[] table = this.getTableAcquire();
++ for (int i = 0, len = table.length; i < len; ++i) {
++ for (TableEntry<K, V> curr = ArrayUtil.getOpaque(table, i); curr != null; curr = curr.getNextOpaque()) {
++ final V value = curr.getValueAcquire();
++
++ action.accept(curr.key, value);
++ }
++ }
++ }
++
++ /**
++ * Provides the specified consumer with all keys contained within this map.
++ * @param action The specified consumer.
++ */
++ public void forEachKey(final Consumer<? super K> action) {
++ Validate.notNull(action, "Null action");
++
++ final TableEntry<K, V>[] table = this.getTableAcquire();
++ for (int i = 0, len = table.length; i < len; ++i) {
++ for (TableEntry<K, V> curr = ArrayUtil.getOpaque(table, i); curr != null; curr = curr.getNextOpaque()) {
++ action.accept(curr.key);
++ }
++ }
++ }
++
++ /**
++ * Provides the specified consumer with all values contained within this map. Equivalent to {@code map.values().forEach(Consumer)}.
++ * @param action The specified consumer.
++ */
++ public void forEachValue(final Consumer<? super V> action) {
++ Validate.notNull(action, "Null action");
++
++ final TableEntry<K, V>[] table = this.getTableAcquire();
++ for (int i = 0, len = table.length; i < len; ++i) {
++ for (TableEntry<K, V> curr = ArrayUtil.getOpaque(table, i); curr != null; curr = curr.getNextOpaque()) {
++ final V value = curr.getValueAcquire();
++
++ action.accept(value);
++ }
++ }
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public V get(final Object key) {
++ Validate.notNull(key, "Null key");
++
++ //noinspection unchecked
++ final TableEntry<K, V> entry = this.getEntryForOpaque((K)key);
++ return entry == null ? null : entry.getValueAcquire();
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public boolean containsKey(final Object key) {
++ Validate.notNull(key, "Null key");
++
++ // note: we need to use getValueAcquire, so that the reads from this map are ordered by acquire semantics
++ return this.get(key) != null;
++ }
++
++ /**
++ * Returns {@code true} if this map contains an entry with the specified key and value at some point during this call.
++ * @param key The specified key.
++ * @param value The specified value.
++ * @return {@code true} if this map contains an entry with the specified key and value.
++ */
++ public boolean contains(final Object key, final Object value) {
++ Validate.notNull(key, "Null key");
++
++ //noinspection unchecked
++ final TableEntry<K, V> entry = this.getEntryForOpaque((K)key);
++
++ if (entry == null) {
++ return false;
++ }
++
++ final V entryVal = entry.getValueAcquire();
++ return entryVal == value || entryVal.equals(value);
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public boolean containsValue(final Object value) {
++ Validate.notNull(value, "Null value");
++
++ final TableEntry<K, V>[] table = this.getTableAcquire();
++ for (int i = 0, len = table.length; i < len; ++i) {
++ for (TableEntry<K, V> curr = ArrayUtil.getOpaque(table, i); curr != null; curr = curr.getNextOpaque()) {
++ final V currVal = curr.getValueAcquire();
++ if (currVal == value || currVal.equals(value)) {
++ return true;
++ }
++ }
++ }
++
++ return false;
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public V getOrDefault(final Object key, final V defaultValue) {
++ Validate.notNull(key, "Null key");
++
++ //noinspection unchecked
++ final TableEntry<K, V> entry = this.getEntryForOpaque((K)key);
++
++ return entry == null ? defaultValue : entry.getValueAcquire();
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public int size() {
++ return this.getSizeAcquire();
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public boolean isEmpty() {
++ return this.getSizeAcquire() == 0;
++ }
++
++ protected Set<K> keyset;
++ protected Collection<V> values;
++ protected Set<Map.Entry<K, V>> entrySet;
++
++ @Override
++ public Set<K> keySet() {
++ return this.keyset == null ? this.keyset = new KeySet<>(this) : this.keyset;
++ }
++
++ @Override
++ public Collection<V> values() {
++ return this.values == null ? this.values = new ValueCollection<>(this) : this.values;
++ }
++
++ @Override
++ public Set<Map.Entry<K, V>> entrySet() {
++ return this.entrySet == null ? this.entrySet = new EntrySet<>(this) : this.entrySet;
++ }
++
++ /* Non-MT-Safe */
++
++ protected int threshold;
++
++ protected final void checkResize(final int minCapacity) {
++ if (minCapacity <= this.threshold || this.threshold < 0) {
++ return;
++ }
++
++ final TableEntry<K, V>[] table = this.getTablePlain();
++ int newCapacity = minCapacity >= MAXIMUM_CAPACITY ? MAXIMUM_CAPACITY : IntegerUtil.roundCeilLog2(minCapacity);
++ if (newCapacity < 0) {
++ newCapacity = MAXIMUM_CAPACITY;
++ }
++ if (newCapacity <= table.length) {
++ if (newCapacity == MAXIMUM_CAPACITY) {
++ return;
++ }
++ newCapacity = table.length << 1;
++ }
++
++ //noinspection unchecked
++ final TableEntry<K, V>[] newTable = new TableEntry[newCapacity];
++ final int indexMask = newCapacity - 1;
++
++ for (int i = 0, len = table.length; i < len; ++i) {
++ for (TableEntry<K, V> entry = table[i]; entry != null; entry = entry.getNextPlain()) {
++ final int hash = entry.hash;
++ final int index = hash & indexMask;
++
++ /* we need to create a new entry since there could be reading threads */
++ final TableEntry<K, V> insert = new TableEntry<>(hash, entry.key, entry.getValuePlain());
++
++ final TableEntry<K, V> prev = newTable[index];
++
++ newTable[index] = insert;
++ insert.setNextPlain(prev);
++ }
++ }
++
++ if (newCapacity == MAXIMUM_CAPACITY) {
++ this.threshold = -1; /* No more resizing */
++ } else {
++ this.threshold = getTargetCapacity(newCapacity, this.loadFactor);
++ }
++ this.setTableRelease(newTable); /* use release to publish entries in table */
++ }
++
++ protected final int addToSize(final int num) {
++ final int newSize = this.getSizePlain() + num;
++
++ this.setSizeOpaque(newSize);
++ this.checkResize(newSize);
++
++ return newSize;
++ }
++
++ protected final int removeFromSize(final int num) {
++ final int newSize = this.getSizePlain() - num;
++
++ this.setSizeOpaque(newSize);
++
++ return newSize;
++ }
++
++ /* Cannot be used to perform downsizing */
++ protected final int removeFromSizePlain(final int num) {
++ final int newSize = this.getSizePlain() - num;
++
++ this.setSizePlain(newSize);
++
++ return newSize;
++ }
++
++ protected final V put(final K key, final V value, final boolean onlyIfAbsent) {
++ final TableEntry<K, V>[] table = this.getTablePlain();
++ final int hash = SWMRHashTable.getHash(key);
++ final int index = hash & (table.length - 1);
++
++ final TableEntry<K, V> head = table[index];
++ if (head == null) {
++ final TableEntry<K, V> insert = new TableEntry<>(hash, key, value);
++ ArrayUtil.setRelease(table, index, insert);
++ this.addToSize(1);
++ return null;
++ }
++
++ for (TableEntry<K, V> curr = head;;) {
++ if (curr.hash == hash && (key == curr.key || curr.key.equals(key))) {
++ if (onlyIfAbsent) {
++ return curr.getValuePlain();
++ }
++
++ final V currVal = curr.getValuePlain();
++ curr.setValueRelease(value);
++ return currVal;
++ }
++
++ final TableEntry<K, V> next = curr.getNextPlain();
++ if (next != null) {
++ curr = next;
++ continue;
++ }
++
++ final TableEntry<K, V> insert = new TableEntry<>(hash, key, value);
++
++ curr.setNextRelease(insert);
++ this.addToSize(1);
++ return null;
++ }
++ }
++
++ /**
++ * Removes a key-value pair from this map if the specified predicate returns true. The specified predicate is
++ * tested with every entry in this map. Returns the number of key-value pairs removed.
++ * @param predicate The predicate to test key-value pairs against.
++ * @return The total number of key-value pairs removed from this map.
++ */
++ public int removeIf(final BiPredicate<K, V> predicate) {
++ Validate.notNull(predicate, "Null predicate");
++
++ int removed = 0;
++
++ final TableEntry<K, V>[] table = this.getTablePlain();
++
++ bin_iteration_loop:
++ for (int i = 0, len = table.length; i < len; ++i) {
++ TableEntry<K, V> curr = table[i];
++ if (curr == null) {
++ continue;
++ }
++
++ /* Handle bin nodes first */
++ while (predicate.test(curr.key, curr.getValuePlain())) {
++ ++removed;
++ this.removeFromSizePlain(1); /* required in case predicate throws an exception */
++
++ ArrayUtil.setRelease(table, i, curr = curr.getNextPlain());
++
++ if (curr == null) {
++ continue bin_iteration_loop;
++ }
++ }
++
++ TableEntry<K, V> prev;
++
++ /* curr at this point is the bin node */
++
++ for (prev = curr, curr = curr.getNextPlain(); curr != null;) {
++ /* If we want to remove, then we should hold prev, as it will be a valid entry to link on */
++ if (predicate.test(curr.key, curr.getValuePlain())) {
++ ++removed;
++ this.removeFromSizePlain(1); /* required in case predicate throws an exception */
++
++ prev.setNextRelease(curr = curr.getNextPlain());
++ } else {
++ prev = curr;
++ curr = curr.getNextPlain();
++ }
++ }
++ }
++
++ return removed;
++ }
++
++ /**
++ * Removes a key-value pair from this map if the specified predicate returns true. The specified predicate is
++ * tested with every entry in this map. Returns the number of key-value pairs removed.
++ * @param predicate The predicate to test key-value pairs against.
++ * @return The total number of key-value pairs removed from this map.
++ */
++ public int removeEntryIf(final Predicate<? super Entry<K, V>> predicate) {
++ Validate.notNull(predicate, "Null predicate");
++
++ int removed = 0;
++
++ final TableEntry<K, V>[] table = this.getTablePlain();
++
++ bin_iteration_loop:
++ for (int i = 0, len = table.length; i < len; ++i) {
++ TableEntry<K, V> curr = table[i];
++ if (curr == null) {
++ continue;
++ }
++
++ /* Handle bin nodes first */
++ while (predicate.test(curr)) {
++ ++removed;
++ this.removeFromSizePlain(1); /* required in case predicate throws an exception */
++
++ ArrayUtil.setRelease(table, i, curr = curr.getNextPlain());
++
++ if (curr == null) {
++ continue bin_iteration_loop;
++ }
++ }
++
++ TableEntry<K, V> prev;
++
++ /* curr at this point is the bin node */
++
++ for (prev = curr, curr = curr.getNextPlain(); curr != null;) {
++ /* If we want to remove, then we should hold prev, as it will be a valid entry to link on */
++ if (predicate.test(curr)) {
++ ++removed;
++ this.removeFromSizePlain(1); /* required in case predicate throws an exception */
++
++ prev.setNextRelease(curr = curr.getNextPlain());
++ } else {
++ prev = curr;
++ curr = curr.getNextPlain();
++ }
++ }
++ }
++
++ return removed;
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public V put(final K key, final V value) {
++ Validate.notNull(key, "Null key");
++ Validate.notNull(value, "Null value");
++
++ return this.put(key, value, false);
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public V putIfAbsent(final K key, final V value) {
++ Validate.notNull(key, "Null key");
++ Validate.notNull(value, "Null value");
++
++ return this.put(key, value, true);
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public boolean remove(final Object key, final Object value) {
++ Validate.notNull(key, "Null key");
++ Validate.notNull(value, "Null value");
++
++ final TableEntry<K, V>[] table = this.getTablePlain();
++ final int hash = SWMRHashTable.getHash(key);
++ final int index = hash & (table.length - 1);
++
++ final TableEntry<K, V> head = table[index];
++ if (head == null) {
++ return false;
++ }
++
++ if (head.hash == hash && (head.key == key || head.key.equals(key))) {
++ final V currVal = head.getValuePlain();
++
++ if (currVal != value && !currVal.equals(value)) {
++ return false;
++ }
++
++ ArrayUtil.setRelease(table, index, head.getNextPlain());
++ this.removeFromSize(1);
++
++ return true;
++ }
++
++ for (TableEntry<K, V> curr = head.getNextPlain(), prev = head; curr != null; prev = curr, curr = curr.getNextPlain()) {
++ if (curr.hash == hash && (curr.key == key || curr.key.equals(key))) {
++ final V currVal = curr.getValuePlain();
++
++ if (currVal != value && !currVal.equals(value)) {
++ return false;
++ }
++
++ prev.setNextRelease(curr.getNextPlain());
++ this.removeFromSize(1);
++
++ return true;
++ }
++ }
++
++ return false;
++ }
++
++ protected final V remove(final Object key, final int hash) {
++ final TableEntry<K, V>[] table = this.getTablePlain();
++ final int index = (table.length - 1) & hash;
++
++ final TableEntry<K, V> head = table[index];
++ if (head == null) {
++ return null;
++ }
++
++ if (hash == head.hash && (head.key == key || head.key.equals(key))) {
++ ArrayUtil.setRelease(table, index, head.getNextPlain());
++ this.removeFromSize(1);
++
++ return head.getValuePlain();
++ }
++
++ for (TableEntry<K, V> curr = head.getNextPlain(), prev = head; curr != null; prev = curr, curr = curr.getNextPlain()) {
++ if (curr.hash == hash && (key == curr.key || curr.key.equals(key))) {
++ prev.setNextRelease(curr.getNextPlain());
++ this.removeFromSize(1);
++
++ return curr.getValuePlain();
++ }
++ }
++
++ return null;
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public V remove(final Object key) {
++ Validate.notNull(key, "Null key");
++
++ return this.remove(key, SWMRHashTable.getHash(key));
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public boolean replace(final K key, final V oldValue, final V newValue) {
++ Validate.notNull(key, "Null key");
++ Validate.notNull(oldValue, "Null oldValue");
++ Validate.notNull(newValue, "Null newValue");
++
++ final TableEntry<K, V> entry = this.getEntryForPlain(key);
++ if (entry == null) {
++ return false;
++ }
++
++ final V currValue = entry.getValuePlain();
++ if (currValue == oldValue || currValue.equals(oldValue)) {
++ entry.setValueRelease(newValue);
++ return true;
++ }
++
++ return false;
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public V replace(final K key, final V value) {
++ Validate.notNull(key, "Null key");
++ Validate.notNull(value, "Null value");
++
++ final TableEntry<K, V> entry = this.getEntryForPlain(key);
++ if (entry == null) {
++ return null;
++ }
++
++ final V prev = entry.getValuePlain();
++ entry.setValueRelease(value);
++ return prev;
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public void replaceAll(final BiFunction<? super K, ? super V, ? extends V> function) {
++ Validate.notNull(function, "Null function");
++
++ final TableEntry<K, V>[] table = this.getTablePlain();
++ for (int i = 0, len = table.length; i < len; ++i) {
++ for (TableEntry<K, V> curr = table[i]; curr != null; curr = curr.getNextPlain()) {
++ final V value = curr.getValuePlain();
++
++ final V newValue = function.apply(curr.key, value);
++ if (newValue == null) {
++ throw new NullPointerException();
++ }
++
++ curr.setValueRelease(newValue);
++ }
++ }
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public void putAll(final Map<? extends K, ? extends V> map) {
++ Validate.notNull(map, "Null map");
++
++ final int size = map.size();
++ this.checkResize(Math.max(this.getSizePlain() + size/2, size)); /* preemptively resize */
++ map.forEach(this::put);
++ }
++
++ /**
++ * {@inheritDoc}
++ * <p>
++ * This call is non-atomic and the order that which entries are removed is undefined. The clear operation itself
++ * is release ordered, that is, after the clear operation is performed a release fence is performed.
++ * </p>
++ */
++ @Override
++ public void clear() {
++ Arrays.fill(this.getTablePlain(), null);
++ this.setSizeRelease(0);
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public V compute(final K key, final BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
++ Validate.notNull(key, "Null key");
++ Validate.notNull(remappingFunction, "Null remappingFunction");
++
++ final int hash = SWMRHashTable.getHash(key);
++ final TableEntry<K, V>[] table = this.getTablePlain();
++ final int index = hash & (table.length - 1);
++
++ for (TableEntry<K, V> curr = table[index], prev = null;;prev = curr, curr = curr.getNextPlain()) {
++ if (curr == null) {
++ final V newVal = remappingFunction.apply(key ,null);
++
++ if (newVal == null) {
++ return null;
++ }
++
++ final TableEntry<K, V> insert = new TableEntry<>(hash, key, newVal);
++ if (prev == null) {
++ ArrayUtil.setRelease(table, index, insert);
++ } else {
++ prev.setNextRelease(insert);
++ }
++
++ this.addToSize(1);
++
++ return newVal;
++ }
++
++ if (curr.hash == hash && (curr.key == key || curr.key.equals(key))) {
++ final V newVal = remappingFunction.apply(key, curr.getValuePlain());
++
++ if (newVal != null) {
++ curr.setValueRelease(newVal);
++ return newVal;
++ }
++
++ if (prev == null) {
++ ArrayUtil.setRelease(table, index, curr.getNextPlain());
++ } else {
++ prev.setNextRelease(curr.getNextPlain());
++ }
++
++ this.removeFromSize(1);
++
++ return null;
++ }
++ }
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public V computeIfPresent(final K key, final BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
++ Validate.notNull(key, "Null key");
++ Validate.notNull(remappingFunction, "Null remappingFunction");
++
++ final int hash = SWMRHashTable.getHash(key);
++ final TableEntry<K, V>[] table = this.getTablePlain();
++ final int index = hash & (table.length - 1);
++
++ for (TableEntry<K, V> curr = table[index], prev = null; curr != null; prev = curr, curr = curr.getNextPlain()) {
++ if (curr.hash != hash || (curr.key != key && !curr.key.equals(key))) {
++ continue;
++ }
++
++ final V newVal = remappingFunction.apply(key, curr.getValuePlain());
++ if (newVal != null) {
++ curr.setValueRelease(newVal);
++ return newVal;
++ }
++
++ if (prev == null) {
++ ArrayUtil.setRelease(table, index, curr.getNextPlain());
++ } else {
++ prev.setNextRelease(curr.getNextPlain());
++ }
++
++ this.removeFromSize(1);
++
++ return null;
++ }
++
++ return null;
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public V computeIfAbsent(final K key, final Function<? super K, ? extends V> mappingFunction) {
++ Validate.notNull(key, "Null key");
++ Validate.notNull(mappingFunction, "Null mappingFunction");
++
++ final int hash = SWMRHashTable.getHash(key);
++ final TableEntry<K, V>[] table = this.getTablePlain();
++ final int index = hash & (table.length - 1);
++
++ for (TableEntry<K, V> curr = table[index], prev = null;;prev = curr, curr = curr.getNextPlain()) {
++ if (curr != null) {
++ if (curr.hash == hash && (curr.key == key || curr.key.equals(key))) {
++ return curr.getValuePlain();
++ }
++ continue;
++ }
++
++ final V newVal = mappingFunction.apply(key);
++
++ if (newVal == null) {
++ return null;
++ }
++
++ final TableEntry<K, V> insert = new TableEntry<>(hash, key, newVal);
++ if (prev == null) {
++ ArrayUtil.setRelease(table, index, insert);
++ } else {
++ prev.setNextRelease(insert);
++ }
++
++ this.addToSize(1);
++
++ return newVal;
++ }
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public V merge(final K key, final V value, final BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
++ Validate.notNull(key, "Null key");
++ Validate.notNull(value, "Null value");
++ Validate.notNull(remappingFunction, "Null remappingFunction");
++
++ final int hash = SWMRHashTable.getHash(key);
++ final TableEntry<K, V>[] table = this.getTablePlain();
++ final int index = hash & (table.length - 1);
++
++ for (TableEntry<K, V> curr = table[index], prev = null;;prev = curr, curr = curr.getNextPlain()) {
++ if (curr == null) {
++ final TableEntry<K, V> insert = new TableEntry<>(hash, key, value);
++ if (prev == null) {
++ ArrayUtil.setRelease(table, index, insert);
++ } else {
++ prev.setNextRelease(insert);
++ }
++
++ this.addToSize(1);
++
++ return value;
++ }
++
++ if (curr.hash == hash && (curr.key == key || curr.key.equals(key))) {
++ final V newVal = remappingFunction.apply(curr.getValuePlain(), value);
++
++ if (newVal != null) {
++ curr.setValueRelease(newVal);
++ return newVal;
++ }
++
++ if (prev == null) {
++ ArrayUtil.setRelease(table, index, curr.getNextPlain());
++ } else {
++ prev.setNextRelease(curr.getNextPlain());
++ }
++
++ this.removeFromSize(1);
++
++ return null;
++ }
++ }
++ }
++
++ protected static final class TableEntry<K, V> implements Map.Entry<K, V> {
++
++ protected final int hash;
++ protected final K key;
++ protected V value;
++
++ protected TableEntry<K, V> next;
++
++ protected static final VarHandle VALUE_HANDLE = ConcurrentUtil.getVarHandle(TableEntry.class, "value", Object.class);
++ protected static final VarHandle NEXT_HANDLE = ConcurrentUtil.getVarHandle(TableEntry.class, "next", TableEntry.class);
++
++ /* value */
++
++ protected final V getValuePlain() {
++ //noinspection unchecked
++ return (V)VALUE_HANDLE.get(this);
++ }
++
++ protected final V getValueAcquire() {
++ //noinspection unchecked
++ return (V)VALUE_HANDLE.getAcquire(this);
++ }
++
++ protected final void setValueRelease(final V to) {
++ VALUE_HANDLE.setRelease(this, to);
++ }
++
++ /* next */
++
++ protected final TableEntry<K, V> getNextPlain() {
++ //noinspection unchecked
++ return (TableEntry<K, V>)NEXT_HANDLE.get(this);
++ }
++
++ protected final TableEntry<K, V> getNextOpaque() {
++ //noinspection unchecked
++ return (TableEntry<K, V>)NEXT_HANDLE.getOpaque(this);
++ }
++
++ protected final void setNextPlain(final TableEntry<K, V> next) {
++ NEXT_HANDLE.set(this, next);
++ }
++
++ protected final void setNextRelease(final TableEntry<K, V> next) {
++ NEXT_HANDLE.setRelease(this, next);
++ }
++
++ protected TableEntry(final int hash, final K key, final V value) {
++ this.hash = hash;
++ this.key = key;
++ this.value = value;
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public K getKey() {
++ return this.key;
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public V getValue() {
++ return this.getValueAcquire();
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public V setValue(final V value) {
++ if (value == null) {
++ throw new NullPointerException();
++ }
++
++ final V curr = this.getValuePlain();
++
++ this.setValueRelease(value);
++ return curr;
++ }
++
++ protected static int hash(final Object key, final Object value) {
++ return key.hashCode() ^ (value == null ? 0 : value.hashCode());
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public int hashCode() {
++ return hash(this.key, this.getValueAcquire());
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public boolean equals(final Object obj) {
++ if (this == obj) {
++ return true;
++ }
++
++ if (!(obj instanceof Map.Entry)) {
++ return false;
++ }
++ final Map.Entry<?, ?> other = (Map.Entry<?, ?>)obj;
++ final Object otherKey = other.getKey();
++ final Object otherValue = other.getValue();
++
++ final K thisKey = this.getKey();
++ final V thisVal = this.getValueAcquire();
++ return (thisKey == otherKey || thisKey.equals(otherKey)) &&
++ (thisVal == otherValue || thisVal.equals(otherValue));
++ }
++ }
++
++
++ protected static abstract class TableEntryIterator<K, V, T> implements Iterator<T> {
++
++ protected final TableEntry<K, V>[] table;
++ protected final SWMRHashTable<K, V> map;
++
++ /* bin which our current element resides on */
++ protected int tableIndex;
++
++ protected TableEntry<K, V> currEntry; /* curr entry, null if no more to iterate or if curr was removed or if we've just init'd */
++ protected TableEntry<K, V> nextEntry; /* may not be on the same bin as currEntry */
++
++ protected TableEntryIterator(final TableEntry<K, V>[] table, final SWMRHashTable<K, V> map) {
++ this.table = table;
++ this.map = map;
++ int tableIndex = 0;
++ for (int len = table.length; tableIndex < len; ++tableIndex) {
++ final TableEntry<K, V> entry = ArrayUtil.getOpaque(table, tableIndex);
++ if (entry != null) {
++ this.nextEntry = entry;
++ this.tableIndex = tableIndex + 1;
++ return;
++ }
++ }
++ this.tableIndex = tableIndex;
++ }
++
++ @Override
++ public boolean hasNext() {
++ return this.nextEntry != null;
++ }
++
++ protected final TableEntry<K, V> advanceEntry() {
++ final TableEntry<K, V>[] table = this.table;
++ final int tableLength = table.length;
++ int tableIndex = this.tableIndex;
++ final TableEntry<K, V> curr = this.nextEntry;
++ if (curr == null) {
++ return null;
++ }
++
++ this.currEntry = curr;
++
++ // set up nextEntry
++
++ // find next in chain
++ TableEntry<K, V> next = curr.getNextOpaque();
++
++ if (next != null) {
++ this.nextEntry = next;
++ return curr;
++ }
++
++ // nothing in chain, so find next available bin
++ for (;tableIndex < tableLength; ++tableIndex) {
++ next = ArrayUtil.getOpaque(table, tableIndex);
++ if (next != null) {
++ this.nextEntry = next;
++ this.tableIndex = tableIndex + 1;
++ return curr;
++ }
++ }
++
++ this.nextEntry = null;
++ this.tableIndex = tableIndex;
++ return curr;
++ }
++
++ @Override
++ public void remove() {
++ final TableEntry<K, V> curr = this.currEntry;
++ if (curr == null) {
++ throw new IllegalStateException();
++ }
++
++ this.map.remove(curr.key, curr.hash);
++
++ this.currEntry = null;
++ }
++ }
++
++ protected static final class ValueIterator<K, V> extends TableEntryIterator<K, V, V> {
++
++ protected ValueIterator(final TableEntry<K, V>[] table, final SWMRHashTable<K, V> map) {
++ super(table, map);
++ }
++
++ @Override
++ public V next() {
++ final TableEntry<K, V> entry = this.advanceEntry();
++
++ if (entry == null) {
++ throw new NoSuchElementException();
++ }
++
++ return entry.getValueAcquire();
++ }
++ }
++
++ protected static final class KeyIterator<K, V> extends TableEntryIterator<K, V, K> {
++
++ protected KeyIterator(final TableEntry<K, V>[] table, final SWMRHashTable<K, V> map) {
++ super(table, map);
++ }
++
++ @Override
++ public K next() {
++ final TableEntry<K, V> curr = this.advanceEntry();
++
++ if (curr == null) {
++ throw new NoSuchElementException();
++ }
++
++ return curr.key;
++ }
++ }
++
++ protected static final class EntryIterator<K, V> extends TableEntryIterator<K, V, Map.Entry<K, V>> {
++
++ protected EntryIterator(final TableEntry<K, V>[] table, final SWMRHashTable<K, V> map) {
++ super(table, map);
++ }
++
++ @Override
++ public Map.Entry<K, V> next() {
++ final TableEntry<K, V> curr = this.advanceEntry();
++
++ if (curr == null) {
++ throw new NoSuchElementException();
++ }
++
++ return curr;
++ }
++ }
++
++ protected static abstract class ViewCollection<K, V, T> implements Collection<T> {
++
++ protected final SWMRHashTable<K, V> map;
++
++ protected ViewCollection(final SWMRHashTable<K, V> map) {
++ this.map = map;
++ }
++
++ @Override
++ public boolean add(final T element) {
++ throw new UnsupportedOperationException();
++ }
++
++ @Override
++ public boolean addAll(final Collection<? extends T> collections) {
++ throw new UnsupportedOperationException();
++ }
++
++ @Override
++ public boolean removeAll(final Collection<?> collection) {
++ Validate.notNull(collection, "Null collection");
++
++ boolean modified = false;
++ for (final Object element : collection) {
++ modified |= this.remove(element);
++ }
++ return modified;
++ }
++
++ @Override
++ public int size() {
++ return this.map.size();
++ }
++
++ @Override
++ public boolean isEmpty() {
++ return this.size() == 0;
++ }
++
++ @Override
++ public void clear() {
++ this.map.clear();
++ }
++
++ @Override
++ public boolean containsAll(final Collection<?> collection) {
++ Validate.notNull(collection, "Null collection");
++
++ for (final Object element : collection) {
++ if (!this.contains(element)) {
++ return false;
++ }
++ }
++
++ return true;
++ }
++
++ @Override
++ public Object[] toArray() {
++ final List<T> list = new ArrayList<>(this.size());
++
++ this.forEach(list::add);
++
++ return list.toArray();
++ }
++
++ @Override
++ public <E> E[] toArray(final E[] array) {
++ final List<T> list = new ArrayList<>(this.size());
++
++ this.forEach(list::add);
++
++ return list.toArray(array);
++ }
++
++ @Override
++ public <E> E[] toArray(final IntFunction<E[]> generator) {
++ final List<T> list = new ArrayList<>(this.size());
++
++ this.forEach(list::add);
++
++ return list.toArray(generator);
++ }
++
++ @Override
++ public int hashCode() {
++ int hash = 0;
++ for (final T element : this) {
++ hash += element == null ? 0 : element.hashCode();
++ }
++ return hash;
++ }
++
++ @Override
++ public Spliterator<T> spliterator() { // TODO implement
++ return Spliterators.spliterator(this, Spliterator.NONNULL);
++ }
++ }
++
++ protected static abstract class ViewSet<K, V, T> extends ViewCollection<K, V, T> implements Set<T> {
++
++ protected ViewSet(final SWMRHashTable<K, V> map) {
++ super(map);
++ }
++
++ @Override
++ public boolean equals(final Object obj) {
++ if (this == obj) {
++ return true;
++ }
++
++ if (!(obj instanceof Set)) {
++ return false;
++ }
++
++ final Set<?> other = (Set<?>)obj;
++ if (other.size() != this.size()) {
++ return false;
++ }
++
++ return this.containsAll(other);
++ }
++ }
++
++ protected static final class EntrySet<K, V> extends ViewSet<K, V, Map.Entry<K, V>> implements Set<Map.Entry<K, V>> {
++
++ protected EntrySet(final SWMRHashTable<K, V> map) {
++ super(map);
++ }
++
++ @Override
++ public boolean remove(final Object object) {
++ if (!(object instanceof Map.Entry<?, ?>)) {
++ return false;
++ }
++ final Map.Entry<?, ?> entry = (Map.Entry<?, ?>)object;
++
++ final Object key;
++ final Object value;
++
++ try {
++ key = entry.getKey();
++ value = entry.getValue();
++ } catch (final IllegalStateException ex) {
++ return false;
++ }
++
++ return this.map.remove(key, value);
++ }
++
++ @Override
++ public boolean removeIf(final Predicate<? super Map.Entry<K, V>> filter) {
++ Validate.notNull(filter, "Null filter");
++
++ return this.map.removeEntryIf(filter) != 0;
++ }
++
++ @Override
++ public boolean retainAll(final Collection<?> collection) {
++ Validate.notNull(collection, "Null collection");
++
++ return this.map.removeEntryIf((final Map.Entry<K, V> entry) -> {
++ return !collection.contains(entry);
++ }) != 0;
++ }
++
++ @Override
++ public Iterator<Entry<K, V>> iterator() {
++ return new EntryIterator<>(this.map.getTableAcquire(), this.map);
++ }
++
++ @Override
++ public void forEach(final Consumer<? super Entry<K, V>> action) {
++ this.map.forEach(action);
++ }
++
++ @Override
++ public boolean contains(final Object object) {
++ if (!(object instanceof Map.Entry)) {
++ return false;
++ }
++ final Map.Entry<?, ?> entry = (Map.Entry<?, ?>)object;
++
++ final Object key;
++ final Object value;
++
++ try {
++ key = entry.getKey();
++ value = entry.getValue();
++ } catch (final IllegalStateException ex) {
++ return false;
++ }
++
++ return this.map.contains(key, value);
++ }
++
++ @Override
++ public String toString() {
++ return CollectionUtil.toString(this, "SWMRHashTableEntrySet");
++ }
++ }
++
++ protected static final class KeySet<K, V> extends ViewSet<K, V, K> {
++
++ protected KeySet(final SWMRHashTable<K, V> map) {
++ super(map);
++ }
++
++ @Override
++ public Iterator<K> iterator() {
++ return new KeyIterator<>(this.map.getTableAcquire(), this.map);
++ }
++
++ @Override
++ public void forEach(final Consumer<? super K> action) {
++ Validate.notNull(action, "Null action");
++
++ this.map.forEachKey(action);
++ }
++
++ @Override
++ public boolean contains(final Object key) {
++ Validate.notNull(key, "Null key");
++
++ return this.map.containsKey(key);
++ }
++
++ @Override
++ public boolean remove(final Object key) {
++ Validate.notNull(key, "Null key");
++
++ return this.map.remove(key) != null;
++ }
++
++ @Override
++ public boolean retainAll(final Collection<?> collection) {
++ Validate.notNull(collection, "Null collection");
++
++ return this.map.removeIf((final K key, final V value) -> {
++ return !collection.contains(key);
++ }) != 0;
++ }
++
++ @Override
++ public boolean removeIf(final Predicate<? super K> filter) {
++ Validate.notNull(filter, "Null filter");
++
++ return this.map.removeIf((final K key, final V value) -> {
++ return filter.test(key);
++ }) != 0;
++ }
++
++ @Override
++ public String toString() {
++ return CollectionUtil.toString(this, "SWMRHashTableKeySet");
++ }
++ }
++
++ protected static final class ValueCollection<K, V> extends ViewSet<K, V, V> implements Collection<V> {
++
++ protected ValueCollection(final SWMRHashTable<K, V> map) {
++ super(map);
++ }
++
++ @Override
++ public Iterator<V> iterator() {
++ return new ValueIterator<>(this.map.getTableAcquire(), this.map);
++ }
++
++ @Override
++ public void forEach(final Consumer<? super V> action) {
++ Validate.notNull(action, "Null action");
++
++ this.map.forEachValue(action);
++ }
++
++ @Override
++ public boolean contains(final Object object) {
++ Validate.notNull(object, "Null object");
++
++ return this.map.containsValue(object);
++ }
++
++ @Override
++ public boolean remove(final Object object) {
++ Validate.notNull(object, "Null object");
++
++ final Iterator<V> itr = this.iterator();
++ while (itr.hasNext()) {
++ final V val = itr.next();
++ if (val == object || val.equals(object)) {
++ itr.remove();
++ return true;
++ }
++ }
++
++ return false;
++ }
++
++ @Override
++ public boolean removeIf(final Predicate<? super V> filter) {
++ Validate.notNull(filter, "Null filter");
++
++ return this.map.removeIf((final K key, final V value) -> {
++ return filter.test(value);
++ }) != 0;
++ }
++
++ @Override
++ public boolean retainAll(final Collection<?> collection) {
++ Validate.notNull(collection, "Null collection");
++
++ return this.map.removeIf((final K key, final V value) -> {
++ return !collection.contains(value);
++ }) != 0;
++ }
++
++ @Override
++ public String toString() {
++ return CollectionUtil.toString(this, "SWMRHashTableValues");
++ }
++ }
++}
+diff --git a/src/main/java/ca/spottedleaf/concurrentutil/map/SWMRLong2ObjectHashTable.java b/src/main/java/ca/spottedleaf/concurrentutil/map/SWMRLong2ObjectHashTable.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..1e98f778ffa0a7bb00ebccaaa8bde075183e41f0
+--- /dev/null
++++ b/src/main/java/ca/spottedleaf/concurrentutil/map/SWMRLong2ObjectHashTable.java
+@@ -0,0 +1,672 @@
++package ca.spottedleaf.concurrentutil.map;
++
++import ca.spottedleaf.concurrentutil.util.ArrayUtil;
++import ca.spottedleaf.concurrentutil.util.ConcurrentUtil;
++import ca.spottedleaf.concurrentutil.util.Validate;
++import io.papermc.paper.util.IntegerUtil;
++import java.lang.invoke.VarHandle;
++import java.util.Arrays;
++import java.util.function.Consumer;
++import java.util.function.LongConsumer;
++
++// trimmed down version of SWMRHashTable
++public class SWMRLong2ObjectHashTable<V> {
++
++ protected int size;
++
++ protected TableEntry<V>[] table;
++
++ protected final float loadFactor;
++
++ protected static final VarHandle SIZE_HANDLE = ConcurrentUtil.getVarHandle(SWMRLong2ObjectHashTable.class, "size", int.class);
++ protected static final VarHandle TABLE_HANDLE = ConcurrentUtil.getVarHandle(SWMRLong2ObjectHashTable.class, "table", TableEntry[].class);
++
++ /* size */
++
++ protected final int getSizePlain() {
++ return (int)SIZE_HANDLE.get(this);
++ }
++
++ protected final int getSizeOpaque() {
++ return (int)SIZE_HANDLE.getOpaque(this);
++ }
++
++ protected final int getSizeAcquire() {
++ return (int)SIZE_HANDLE.getAcquire(this);
++ }
++
++ protected final void setSizePlain(final int value) {
++ SIZE_HANDLE.set(this, value);
++ }
++
++ protected final void setSizeOpaque(final int value) {
++ SIZE_HANDLE.setOpaque(this, value);
++ }
++
++ protected final void setSizeRelease(final int value) {
++ SIZE_HANDLE.setRelease(this, value);
++ }
++
++ /* table */
++
++ protected final TableEntry<V>[] getTablePlain() {
++ //noinspection unchecked
++ return (TableEntry<V>[])TABLE_HANDLE.get(this);
++ }
++
++ protected final TableEntry<V>[] getTableAcquire() {
++ //noinspection unchecked
++ return (TableEntry<V>[])TABLE_HANDLE.getAcquire(this);
++ }
++
++ protected final void setTablePlain(final TableEntry<V>[] table) {
++ TABLE_HANDLE.set(this, table);
++ }
++
++ protected final void setTableRelease(final TableEntry<V>[] table) {
++ TABLE_HANDLE.setRelease(this, table);
++ }
++
++ protected static final int DEFAULT_CAPACITY = 16;
++ protected static final float DEFAULT_LOAD_FACTOR = 0.75f;
++ protected static final int MAXIMUM_CAPACITY = Integer.MIN_VALUE >>> 1;
++
++ /**
++ * Constructs this map with a capacity of {@code 16} and load factor of {@code 0.75f}.
++ */
++ public SWMRLong2ObjectHashTable() {
++ this(DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR);
++ }
++
++ /**
++ * Constructs this map with the specified capacity and load factor of {@code 0.75f}.
++ * @param capacity specified initial capacity, > 0
++ */
++ public SWMRLong2ObjectHashTable(final int capacity) {
++ this(capacity, DEFAULT_LOAD_FACTOR);
++ }
++
++ /**
++ * Constructs this map with the specified capacity and load factor.
++ * @param capacity specified capacity, > 0
++ * @param loadFactor specified load factor, > 0 && finite
++ */
++ public SWMRLong2ObjectHashTable(final int capacity, final float loadFactor) {
++ final int tableSize = getCapacityFor(capacity);
++
++ if (loadFactor <= 0.0 || !Float.isFinite(loadFactor)) {
++ throw new IllegalArgumentException("Invalid load factor: " + loadFactor);
++ }
++
++ //noinspection unchecked
++ final TableEntry<V>[] table = new TableEntry[tableSize];
++ this.setTablePlain(table);
++
++ if (tableSize == MAXIMUM_CAPACITY) {
++ this.threshold = -1;
++ } else {
++ this.threshold = getTargetCapacity(tableSize, loadFactor);
++ }
++
++ this.loadFactor = loadFactor;
++ }
++
++ /**
++ * Constructs this map with a capacity of {@code 16} or the specified map's size, whichever is larger, and
++ * with a load factor of {@code 0.75f}.
++ * All of the specified map's entries are copied into this map.
++ * @param other The specified map.
++ */
++ public SWMRLong2ObjectHashTable(final SWMRLong2ObjectHashTable<V> other) {
++ this(DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR, other);
++ }
++
++ /**
++ * Constructs this map with a minimum capacity of the specified capacity or the specified map's size, whichever is larger, and
++ * with a load factor of {@code 0.75f}.
++ * All of the specified map's entries are copied into this map.
++ * @param capacity specified capacity, > 0
++ * @param other The specified map.
++ */
++ public SWMRLong2ObjectHashTable(final int capacity, final SWMRLong2ObjectHashTable<V> other) {
++ this(capacity, DEFAULT_LOAD_FACTOR, other);
++ }
++
++ /**
++ * Constructs this map with a min capacity of the specified capacity or the specified map's size, whichever is larger, and
++ * with the specified load factor.
++ * All of the specified map's entries are copied into this map.
++ * @param capacity specified capacity, > 0
++ * @param loadFactor specified load factor, > 0 && finite
++ * @param other The specified map.
++ */
++ public SWMRLong2ObjectHashTable(final int capacity, final float loadFactor, final SWMRLong2ObjectHashTable<V> other) {
++ this(Math.max(Validate.notNull(other, "Null map").size(), capacity), loadFactor);
++ this.putAll(other);
++ }
++
++ public final float getLoadFactor() {
++ return this.loadFactor;
++ }
++
++ protected static int getCapacityFor(final int capacity) {
++ if (capacity <= 0) {
++ throw new IllegalArgumentException("Invalid capacity: " + capacity);
++ }
++ if (capacity >= MAXIMUM_CAPACITY) {
++ return MAXIMUM_CAPACITY;
++ }
++ return IntegerUtil.roundCeilLog2(capacity);
++ }
++
++ /** Callers must still use acquire when reading the value of the entry. */
++ protected final TableEntry<V> getEntryForOpaque(final long key) {
++ final int hash = SWMRLong2ObjectHashTable.getHash(key);
++ final TableEntry<V>[] table = this.getTableAcquire();
++
++ for (TableEntry<V> curr = ArrayUtil.getOpaque(table, hash & (table.length - 1)); curr != null; curr = curr.getNextOpaque()) {
++ if (key == curr.key) {
++ return curr;
++ }
++ }
++
++ return null;
++ }
++
++ protected final TableEntry<V> getEntryForPlain(final long key) {
++ final int hash = SWMRLong2ObjectHashTable.getHash(key);
++ final TableEntry<V>[] table = this.getTablePlain();
++
++ for (TableEntry<V> curr = table[hash & (table.length - 1)]; curr != null; curr = curr.getNextPlain()) {
++ if (key == curr.key) {
++ return curr;
++ }
++ }
++
++ return null;
++ }
++
++ /* MT-Safe */
++
++ /** must be deterministic given a key */
++ protected static int getHash(final long key) {
++ return (int)it.unimi.dsi.fastutil.HashCommon.mix(key);
++ }
++
++ // rets -1 if capacity*loadFactor is too large
++ protected static int getTargetCapacity(final int capacity, final float loadFactor) {
++ final double ret = (double)capacity * (double)loadFactor;
++ if (Double.isInfinite(ret) || ret >= ((double)Integer.MAX_VALUE)) {
++ return -1;
++ }
++
++ return (int)ret;
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public boolean equals(final Object obj) {
++ if (this == obj) {
++ return true;
++ }
++ /* Make no attempt to deal with concurrent modifications */
++ if (!(obj instanceof SWMRLong2ObjectHashTable)) {
++ return false;
++ }
++ final SWMRLong2ObjectHashTable<?> other = (SWMRLong2ObjectHashTable<?>)obj;
++
++ if (this.size() != other.size()) {
++ return false;
++ }
++
++ final TableEntry<V>[] table = this.getTableAcquire();
++
++ for (int i = 0, len = table.length; i < len; ++i) {
++ for (TableEntry<V> curr = ArrayUtil.getOpaque(table, i); curr != null; curr = curr.getNextOpaque()) {
++ final V value = curr.getValueAcquire();
++
++ final Object otherValue = other.get(curr.key);
++ if (otherValue == null || (value != otherValue && value.equals(otherValue))) {
++ return false;
++ }
++ }
++ }
++
++ return true;
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public int hashCode() {
++ /* Make no attempt to deal with concurrent modifications */
++ int hash = 0;
++ final TableEntry<V>[] table = this.getTableAcquire();
++
++ for (int i = 0, len = table.length; i < len; ++i) {
++ for (TableEntry<V> curr = ArrayUtil.getOpaque(table, i); curr != null; curr = curr.getNextOpaque()) {
++ hash += curr.hashCode();
++ }
++ }
++
++ return hash;
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public String toString() {
++ final StringBuilder builder = new StringBuilder(64);
++ builder.append("SingleWriterMultiReaderHashMap:{");
++
++ this.forEach((final long key, final V value) -> {
++ builder.append("{key: \"").append(key).append("\", value: \"").append(value).append("\"}");
++ });
++
++ return builder.append('}').toString();
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public SWMRLong2ObjectHashTable<V> clone() {
++ return new SWMRLong2ObjectHashTable<>(this.getTableAcquire().length, this.loadFactor, this);
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ public void forEach(final Consumer<? super SWMRLong2ObjectHashTable.TableEntry<V>> action) {
++ Validate.notNull(action, "Null action");
++
++ final TableEntry<V>[] table = this.getTableAcquire();
++ for (int i = 0, len = table.length; i < len; ++i) {
++ for (TableEntry<V> curr = ArrayUtil.getOpaque(table, i); curr != null; curr = curr.getNextOpaque()) {
++ action.accept(curr);
++ }
++ }
++ }
++
++ @FunctionalInterface
++ public static interface BiLongObjectConsumer<V> {
++ public void accept(final long key, final V value);
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ public void forEach(final BiLongObjectConsumer<? super V> action) {
++ Validate.notNull(action, "Null action");
++
++ final TableEntry<V>[] table = this.getTableAcquire();
++ for (int i = 0, len = table.length; i < len; ++i) {
++ for (TableEntry<V> curr = ArrayUtil.getOpaque(table, i); curr != null; curr = curr.getNextOpaque()) {
++ final V value = curr.getValueAcquire();
++
++ action.accept(curr.key, value);
++ }
++ }
++ }
++
++ /**
++ * Provides the specified consumer with all keys contained within this map.
++ * @param action The specified consumer.
++ */
++ public void forEachKey(final LongConsumer action) {
++ Validate.notNull(action, "Null action");
++
++ final TableEntry<V>[] table = this.getTableAcquire();
++ for (int i = 0, len = table.length; i < len; ++i) {
++ for (TableEntry<V> curr = ArrayUtil.getOpaque(table, i); curr != null; curr = curr.getNextOpaque()) {
++ action.accept(curr.key);
++ }
++ }
++ }
++
++ /**
++ * Provides the specified consumer with all values contained within this map. Equivalent to {@code map.values().forEach(Consumer)}.
++ * @param action The specified consumer.
++ */
++ public void forEachValue(final Consumer<? super V> action) {
++ Validate.notNull(action, "Null action");
++
++ final TableEntry<V>[] table = this.getTableAcquire();
++ for (int i = 0, len = table.length; i < len; ++i) {
++ for (TableEntry<V> curr = ArrayUtil.getOpaque(table, i); curr != null; curr = curr.getNextOpaque()) {
++ final V value = curr.getValueAcquire();
++
++ action.accept(value);
++ }
++ }
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ public V get(final long key) {
++ final TableEntry<V> entry = this.getEntryForOpaque(key);
++ return entry == null ? null : entry.getValueAcquire();
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ public boolean containsKey(final long key) {
++ // note: we need to use getValueAcquire, so that the reads from this map are ordered by acquire semantics
++ return this.get(key) != null;
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ public V getOrDefault(final long key, final V defaultValue) {
++ final TableEntry<V> entry = this.getEntryForOpaque(key);
++
++ return entry == null ? defaultValue : entry.getValueAcquire();
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ public int size() {
++ return this.getSizeAcquire();
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ public boolean isEmpty() {
++ return this.getSizeAcquire() == 0;
++ }
++
++ /* Non-MT-Safe */
++
++ protected int threshold;
++
++ protected final void checkResize(final int minCapacity) {
++ if (minCapacity <= this.threshold || this.threshold < 0) {
++ return;
++ }
++
++ final TableEntry<V>[] table = this.getTablePlain();
++ int newCapacity = minCapacity >= MAXIMUM_CAPACITY ? MAXIMUM_CAPACITY : IntegerUtil.roundCeilLog2(minCapacity);
++ if (newCapacity < 0) {
++ newCapacity = MAXIMUM_CAPACITY;
++ }
++ if (newCapacity <= table.length) {
++ if (newCapacity == MAXIMUM_CAPACITY) {
++ return;
++ }
++ newCapacity = table.length << 1;
++ }
++
++ //noinspection unchecked
++ final TableEntry<V>[] newTable = new TableEntry[newCapacity];
++ final int indexMask = newCapacity - 1;
++
++ for (int i = 0, len = table.length; i < len; ++i) {
++ for (TableEntry<V> entry = table[i]; entry != null; entry = entry.getNextPlain()) {
++ final long key = entry.key;
++ final int hash = SWMRLong2ObjectHashTable.getHash(key);
++ final int index = hash & indexMask;
++
++ /* we need to create a new entry since there could be reading threads */
++ final TableEntry<V> insert = new TableEntry<>(key, entry.getValuePlain());
++
++ final TableEntry<V> prev = newTable[index];
++
++ newTable[index] = insert;
++ insert.setNextPlain(prev);
++ }
++ }
++
++ if (newCapacity == MAXIMUM_CAPACITY) {
++ this.threshold = -1; /* No more resizing */
++ } else {
++ this.threshold = getTargetCapacity(newCapacity, this.loadFactor);
++ }
++ this.setTableRelease(newTable); /* use release to publish entries in table */
++ }
++
++ protected final int addToSize(final int num) {
++ final int newSize = this.getSizePlain() + num;
++
++ this.setSizeOpaque(newSize);
++ this.checkResize(newSize);
++
++ return newSize;
++ }
++
++ protected final int removeFromSize(final int num) {
++ final int newSize = this.getSizePlain() - num;
++
++ this.setSizeOpaque(newSize);
++
++ return newSize;
++ }
++
++ protected final V put(final long key, final V value, final boolean onlyIfAbsent) {
++ final TableEntry<V>[] table = this.getTablePlain();
++ final int hash = SWMRLong2ObjectHashTable.getHash(key);
++ final int index = hash & (table.length - 1);
++
++ final TableEntry<V> head = table[index];
++ if (head == null) {
++ final TableEntry<V> insert = new TableEntry<>(key, value);
++ ArrayUtil.setRelease(table, index, insert);
++ this.addToSize(1);
++ return null;
++ }
++
++ for (TableEntry<V> curr = head;;) {
++ if (key == curr.key) {
++ if (onlyIfAbsent) {
++ return curr.getValuePlain();
++ }
++
++ final V currVal = curr.getValuePlain();
++ curr.setValueRelease(value);
++ return currVal;
++ }
++
++ final TableEntry<V> next = curr.getNextPlain();
++ if (next != null) {
++ curr = next;
++ continue;
++ }
++
++ final TableEntry<V> insert = new TableEntry<>(key, value);
++
++ curr.setNextRelease(insert);
++ this.addToSize(1);
++ return null;
++ }
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ public V put(final long key, final V value) {
++ Validate.notNull(value, "Null value");
++
++ return this.put(key, value, false);
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ public V putIfAbsent(final long key, final V value) {
++ Validate.notNull(value, "Null value");
++
++ return this.put(key, value, true);
++ }
++
++ protected final V remove(final long key, final int hash) {
++ final TableEntry<V>[] table = this.getTablePlain();
++ final int index = (table.length - 1) & hash;
++
++ final TableEntry<V> head = table[index];
++ if (head == null) {
++ return null;
++ }
++
++ if (head.key == key) {
++ ArrayUtil.setRelease(table, index, head.getNextPlain());
++ this.removeFromSize(1);
++
++ return head.getValuePlain();
++ }
++
++ for (TableEntry<V> curr = head.getNextPlain(), prev = head; curr != null; prev = curr, curr = curr.getNextPlain()) {
++ if (key == curr.key) {
++ prev.setNextRelease(curr.getNextPlain());
++ this.removeFromSize(1);
++
++ return curr.getValuePlain();
++ }
++ }
++
++ return null;
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ public V remove(final long key) {
++ return this.remove(key, SWMRLong2ObjectHashTable.getHash(key));
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ public void putAll(final SWMRLong2ObjectHashTable<? extends V> map) {
++ Validate.notNull(map, "Null map");
++
++ final int size = map.size();
++ this.checkResize(Math.max(this.getSizePlain() + size/2, size)); /* preemptively resize */
++ map.forEach(this::put);
++ }
++
++ /**
++ * {@inheritDoc}
++ * <p>
++ * This call is non-atomic and the order that which entries are removed is undefined. The clear operation itself
++ * is release ordered, that is, after the clear operation is performed a release fence is performed.
++ * </p>
++ */
++ public void clear() {
++ Arrays.fill(this.getTablePlain(), null);
++ this.setSizeRelease(0);
++ }
++
++ public static final class TableEntry<V> {
++
++ protected final long key;
++ protected V value;
++
++ protected TableEntry<V> next;
++
++ protected static final VarHandle VALUE_HANDLE = ConcurrentUtil.getVarHandle(TableEntry.class, "value", Object.class);
++ protected static final VarHandle NEXT_HANDLE = ConcurrentUtil.getVarHandle(TableEntry.class, "next", TableEntry.class);
++
++ /* value */
++
++ protected final V getValuePlain() {
++ //noinspection unchecked
++ return (V)VALUE_HANDLE.get(this);
++ }
++
++ protected final V getValueAcquire() {
++ //noinspection unchecked
++ return (V)VALUE_HANDLE.getAcquire(this);
++ }
++
++ protected final void setValueRelease(final V to) {
++ VALUE_HANDLE.setRelease(this, to);
++ }
++
++ /* next */
++
++ protected final TableEntry<V> getNextPlain() {
++ //noinspection unchecked
++ return (TableEntry<V>)NEXT_HANDLE.get(this);
++ }
++
++ protected final TableEntry<V> getNextOpaque() {
++ //noinspection unchecked
++ return (TableEntry<V>)NEXT_HANDLE.getOpaque(this);
++ }
++
++ protected final void setNextPlain(final TableEntry<V> next) {
++ NEXT_HANDLE.set(this, next);
++ }
++
++ protected final void setNextRelease(final TableEntry<V> next) {
++ NEXT_HANDLE.setRelease(this, next);
++ }
++
++ protected TableEntry(final long key, final V value) {
++ this.key = key;
++ this.value = value;
++ }
++
++ public long getKey() {
++ return this.key;
++ }
++
++ public V getValue() {
++ return this.getValueAcquire();
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ public V setValue(final V value) {
++ if (value == null) {
++ throw new NullPointerException();
++ }
++
++ final V curr = this.getValuePlain();
++
++ this.setValueRelease(value);
++ return curr;
++ }
++
++ protected static int hash(final long key, final Object value) {
++ return SWMRLong2ObjectHashTable.getHash(key) ^ (value == null ? 0 : value.hashCode());
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public int hashCode() {
++ return hash(this.key, this.getValueAcquire());
++ }
++
++ /**
++ * {@inheritDoc}
++ */
++ @Override
++ public boolean equals(final Object obj) {
++ if (this == obj) {
++ return true;
++ }
++
++ if (!(obj instanceof TableEntry<?>)) {
++ return false;
++ }
++ final TableEntry<?> other = (TableEntry<?>)obj;
++ final long otherKey = other.getKey();
++ final long thisKey = this.getKey();
++ final Object otherValue = other.getValueAcquire();
++ final V thisVal = this.getValueAcquire();
++ return (thisKey == otherKey) && (thisVal == otherValue || thisVal.equals(otherValue));
++ }
++ }
++}
+diff --git a/src/main/java/ca/spottedleaf/concurrentutil/util/ArrayUtil.java b/src/main/java/ca/spottedleaf/concurrentutil/util/ArrayUtil.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..ebb1ab06165addb173fea4d295001fe37f4e79d3
+--- /dev/null
++++ b/src/main/java/ca/spottedleaf/concurrentutil/util/ArrayUtil.java
+@@ -0,0 +1,816 @@
++package ca.spottedleaf.concurrentutil.util;
++
++import java.lang.invoke.VarHandle;
++
++public final class ArrayUtil {
++
++ public static final VarHandle BOOLEAN_ARRAY_HANDLE = ConcurrentUtil.getArrayHandle(boolean[].class);
++
++ public static final VarHandle BYTE_ARRAY_HANDLE = ConcurrentUtil.getArrayHandle(byte[].class);
++
++ public static final VarHandle SHORT_ARRAY_HANDLE = ConcurrentUtil.getArrayHandle(short[].class);
++
++ public static final VarHandle INT_ARRAY_HANDLE = ConcurrentUtil.getArrayHandle(int[].class);
++
++ public static final VarHandle LONG_ARRAY_HANDLE = ConcurrentUtil.getArrayHandle(long[].class);
++
++ public static final VarHandle OBJECT_ARRAY_HANDLE = ConcurrentUtil.getArrayHandle(Object[].class);
++
++ private ArrayUtil() {
++ throw new RuntimeException();
++ }
++
++ /* byte array */
++
++ public static byte getPlain(final byte[] array, final int index) {
++ return (byte)BYTE_ARRAY_HANDLE.get(array, index);
++ }
++
++ public static byte getOpaque(final byte[] array, final int index) {
++ return (byte)BYTE_ARRAY_HANDLE.getOpaque(array, index);
++ }
++
++ public static byte getAcquire(final byte[] array, final int index) {
++ return (byte)BYTE_ARRAY_HANDLE.getAcquire(array, index);
++ }
++
++ public static byte getVolatile(final byte[] array, final int index) {
++ return (byte)BYTE_ARRAY_HANDLE.getVolatile(array, index);
++ }
++
++ public static void setPlain(final byte[] array, final int index, final byte value) {
++ BYTE_ARRAY_HANDLE.set(array, index, value);
++ }
++
++ public static void setOpaque(final byte[] array, final int index, final byte value) {
++ BYTE_ARRAY_HANDLE.setOpaque(array, index, value);
++ }
++
++ public static void setRelease(final byte[] array, final int index, final byte value) {
++ BYTE_ARRAY_HANDLE.setRelease(array, index, value);
++ }
++
++ public static void setVolatile(final byte[] array, final int index, final byte value) {
++ BYTE_ARRAY_HANDLE.setVolatile(array, index, value);
++ }
++
++ public static void setVolatileContended(final byte[] array, final int index, final byte param) {
++ int failures = 0;
++
++ for (byte curr = getVolatile(array, index);;++failures) {
++ for (int i = 0; i < failures; ++i) {
++ ConcurrentUtil.backoff();
++ }
++
++ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, param))) {
++ return;
++ }
++ }
++ }
++
++ public static byte compareAndExchangeVolatile(final byte[] array, final int index, final byte expect, final byte update) {
++ return (byte)BYTE_ARRAY_HANDLE.compareAndExchange(array, index, expect, update);
++ }
++
++ public static byte getAndAddVolatile(final byte[] array, final int index, final byte param) {
++ return (byte)BYTE_ARRAY_HANDLE.getAndAdd(array, index, param);
++ }
++
++ public static byte getAndAndVolatile(final byte[] array, final int index, final byte param) {
++ return (byte)BYTE_ARRAY_HANDLE.getAndBitwiseAnd(array, index, param);
++ }
++
++ public static byte getAndOrVolatile(final byte[] array, final int index, final byte param) {
++ return (byte)BYTE_ARRAY_HANDLE.getAndBitwiseOr(array, index, param);
++ }
++
++ public static byte getAndXorVolatile(final byte[] array, final int index, final byte param) {
++ return (byte)BYTE_ARRAY_HANDLE.getAndBitwiseXor(array, index, param);
++ }
++
++ public static byte getAndSetVolatile(final byte[] array, final int index, final byte param) {
++ return (byte)BYTE_ARRAY_HANDLE.getAndSet(array, index, param);
++ }
++
++ public static byte compareAndExchangeVolatileContended(final byte[] array, final int index, final byte expect, final byte update) {
++ return (byte)BYTE_ARRAY_HANDLE.compareAndExchange(array, index, expect, update);
++ }
++
++ public static byte getAndAddVolatileContended(final byte[] array, final int index, final byte param) {
++ int failures = 0;
++
++ for (byte curr = getVolatile(array, index);;++failures) {
++ for (int i = 0; i < failures; ++i) {
++ ConcurrentUtil.backoff();
++ }
++
++ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, (byte) (curr + param)))) {
++ return curr;
++ }
++ }
++ }
++
++ public static byte getAndAndVolatileContended(final byte[] array, final int index, final byte param) {
++ int failures = 0;
++
++ for (byte curr = getVolatile(array, index);;++failures) {
++ for (int i = 0; i < failures; ++i) {
++ ConcurrentUtil.backoff();
++ }
++
++ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, (byte) (curr & param)))) {
++ return curr;
++ }
++ }
++ }
++
++ public static byte getAndOrVolatileContended(final byte[] array, final int index, final byte param) {
++ int failures = 0;
++
++ for (byte curr = getVolatile(array, index);;++failures) {
++ for (int i = 0; i < failures; ++i) {
++ ConcurrentUtil.backoff();
++ }
++
++ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, (byte) (curr | param)))) {
++ return curr;
++ }
++ }
++ }
++
++ public static byte getAndXorVolatileContended(final byte[] array, final int index, final byte param) {
++ int failures = 0;
++
++ for (byte curr = getVolatile(array, index);;++failures) {
++ for (int i = 0; i < failures; ++i) {
++ ConcurrentUtil.backoff();
++ }
++
++ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, (byte) (curr ^ param)))) {
++ return curr;
++ }
++ }
++ }
++
++ public static byte getAndSetVolatileContended(final byte[] array, final int index, final byte param) {
++ int failures = 0;
++
++ for (byte curr = getVolatile(array, index);;++failures) {
++ for (int i = 0; i < failures; ++i) {
++ ConcurrentUtil.backoff();
++ }
++
++ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, param))) {
++ return curr;
++ }
++ }
++ }
++
++ /* short array */
++
++ public static short getPlain(final short[] array, final int index) {
++ return (short)SHORT_ARRAY_HANDLE.get(array, index);
++ }
++
++ public static short getOpaque(final short[] array, final int index) {
++ return (short)SHORT_ARRAY_HANDLE.getOpaque(array, index);
++ }
++
++ public static short getAcquire(final short[] array, final int index) {
++ return (short)SHORT_ARRAY_HANDLE.getAcquire(array, index);
++ }
++
++ public static short getVolatile(final short[] array, final int index) {
++ return (short)SHORT_ARRAY_HANDLE.getVolatile(array, index);
++ }
++
++ public static void setPlain(final short[] array, final int index, final short value) {
++ SHORT_ARRAY_HANDLE.set(array, index, value);
++ }
++
++ public static void setOpaque(final short[] array, final int index, final short value) {
++ SHORT_ARRAY_HANDLE.setOpaque(array, index, value);
++ }
++
++ public static void setRelease(final short[] array, final int index, final short value) {
++ SHORT_ARRAY_HANDLE.setRelease(array, index, value);
++ }
++
++ public static void setVolatile(final short[] array, final int index, final short value) {
++ SHORT_ARRAY_HANDLE.setVolatile(array, index, value);
++ }
++
++ public static void setVolatileContended(final short[] array, final int index, final short param) {
++ int failures = 0;
++
++ for (short curr = getVolatile(array, index);;++failures) {
++ for (int i = 0; i < failures; ++i) {
++ ConcurrentUtil.backoff();
++ }
++
++ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, param))) {
++ return;
++ }
++ }
++ }
++
++ public static short compareAndExchangeVolatile(final short[] array, final int index, final short expect, final short update) {
++ return (short)SHORT_ARRAY_HANDLE.compareAndExchange(array, index, expect, update);
++ }
++
++ public static short getAndAddVolatile(final short[] array, final int index, final short param) {
++ return (short)SHORT_ARRAY_HANDLE.getAndAdd(array, index, param);
++ }
++
++ public static short getAndAndVolatile(final short[] array, final int index, final short param) {
++ return (short)SHORT_ARRAY_HANDLE.getAndBitwiseAnd(array, index, param);
++ }
++
++ public static short getAndOrVolatile(final short[] array, final int index, final short param) {
++ return (short)SHORT_ARRAY_HANDLE.getAndBitwiseOr(array, index, param);
++ }
++
++ public static short getAndXorVolatile(final short[] array, final int index, final short param) {
++ return (short)SHORT_ARRAY_HANDLE.getAndBitwiseXor(array, index, param);
++ }
++
++ public static short getAndSetVolatile(final short[] array, final int index, final short param) {
++ return (short)SHORT_ARRAY_HANDLE.getAndSet(array, index, param);
++ }
++
++ public static short compareAndExchangeVolatileContended(final short[] array, final int index, final short expect, final short update) {
++ return (short)SHORT_ARRAY_HANDLE.compareAndExchange(array, index, expect, update);
++ }
++
++ public static short getAndAddVolatileContended(final short[] array, final int index, final short param) {
++ int failures = 0;
++
++ for (short curr = getVolatile(array, index);;++failures) {
++ for (int i = 0; i < failures; ++i) {
++ ConcurrentUtil.backoff();
++ }
++
++ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, (short) (curr + param)))) {
++ return curr;
++ }
++ }
++ }
++
++ public static short getAndAndVolatileContended(final short[] array, final int index, final short param) {
++ int failures = 0;
++
++ for (short curr = getVolatile(array, index);;++failures) {
++ for (int i = 0; i < failures; ++i) {
++ ConcurrentUtil.backoff();
++ }
++
++ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, (short) (curr & param)))) {
++ return curr;
++ }
++ }
++ }
++
++ public static short getAndOrVolatileContended(final short[] array, final int index, final short param) {
++ int failures = 0;
++
++ for (short curr = getVolatile(array, index);;++failures) {
++ for (int i = 0; i < failures; ++i) {
++ ConcurrentUtil.backoff();
++ }
++
++ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, (short) (curr | param)))) {
++ return curr;
++ }
++ }
++ }
++
++ public static short getAndXorVolatileContended(final short[] array, final int index, final short param) {
++ int failures = 0;
++
++ for (short curr = getVolatile(array, index);;++failures) {
++ for (int i = 0; i < failures; ++i) {
++ ConcurrentUtil.backoff();
++ }
++
++ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, (short) (curr ^ param)))) {
++ return curr;
++ }
++ }
++ }
++
++ public static short getAndSetVolatileContended(final short[] array, final int index, final short param) {
++ int failures = 0;
++
++ for (short curr = getVolatile(array, index);;++failures) {
++ for (int i = 0; i < failures; ++i) {
++ ConcurrentUtil.backoff();
++ }
++
++ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, param))) {
++ return curr;
++ }
++ }
++ }
++
++ /* int array */
++
++ public static int getPlain(final int[] array, final int index) {
++ return (int)INT_ARRAY_HANDLE.get(array, index);
++ }
++
++ public static int getOpaque(final int[] array, final int index) {
++ return (int)INT_ARRAY_HANDLE.getOpaque(array, index);
++ }
++
++ public static int getAcquire(final int[] array, final int index) {
++ return (int)INT_ARRAY_HANDLE.getAcquire(array, index);
++ }
++
++ public static int getVolatile(final int[] array, final int index) {
++ return (int)INT_ARRAY_HANDLE.getVolatile(array, index);
++ }
++
++ public static void setPlain(final int[] array, final int index, final int value) {
++ INT_ARRAY_HANDLE.set(array, index, value);
++ }
++
++ public static void setOpaque(final int[] array, final int index, final int value) {
++ INT_ARRAY_HANDLE.setOpaque(array, index, value);
++ }
++
++ public static void setRelease(final int[] array, final int index, final int value) {
++ INT_ARRAY_HANDLE.setRelease(array, index, value);
++ }
++
++ public static void setVolatile(final int[] array, final int index, final int value) {
++ INT_ARRAY_HANDLE.setVolatile(array, index, value);
++ }
++
++ public static void setVolatileContended(final int[] array, final int index, final int param) {
++ int failures = 0;
++
++ for (int curr = getVolatile(array, index);;++failures) {
++ for (int i = 0; i < failures; ++i) {
++ ConcurrentUtil.backoff();
++ }
++
++ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, param))) {
++ return;
++ }
++ }
++ }
++
++ public static int compareAndExchangeVolatile(final int[] array, final int index, final int expect, final int update) {
++ return (int)INT_ARRAY_HANDLE.compareAndExchange(array, index, expect, update);
++ }
++
++ public static int getAndAddVolatile(final int[] array, final int index, final int param) {
++ return (int)INT_ARRAY_HANDLE.getAndAdd(array, index, param);
++ }
++
++ public static int getAndAndVolatile(final int[] array, final int index, final int param) {
++ return (int)INT_ARRAY_HANDLE.getAndBitwiseAnd(array, index, param);
++ }
++
++ public static int getAndOrVolatile(final int[] array, final int index, final int param) {
++ return (int)INT_ARRAY_HANDLE.getAndBitwiseOr(array, index, param);
++ }
++
++ public static int getAndXorVolatile(final int[] array, final int index, final int param) {
++ return (int)INT_ARRAY_HANDLE.getAndBitwiseXor(array, index, param);
++ }
++
++ public static int getAndSetVolatile(final int[] array, final int index, final int param) {
++ return (int)INT_ARRAY_HANDLE.getAndSet(array, index, param);
++ }
++
++ public static int compareAndExchangeVolatileContended(final int[] array, final int index, final int expect, final int update) {
++ return (int)INT_ARRAY_HANDLE.compareAndExchange(array, index, expect, update);
++ }
++
++ public static int getAndAddVolatileContended(final int[] array, final int index, final int param) {
++ int failures = 0;
++
++ for (int curr = getVolatile(array, index);;++failures) {
++ for (int i = 0; i < failures; ++i) {
++ ConcurrentUtil.backoff();
++ }
++
++ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, (int) (curr + param)))) {
++ return curr;
++ }
++ }
++ }
++
++ public static int getAndAndVolatileContended(final int[] array, final int index, final int param) {
++ int failures = 0;
++
++ for (int curr = getVolatile(array, index);;++failures) {
++ for (int i = 0; i < failures; ++i) {
++ ConcurrentUtil.backoff();
++ }
++
++ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, (int) (curr & param)))) {
++ return curr;
++ }
++ }
++ }
++
++ public static int getAndOrVolatileContended(final int[] array, final int index, final int param) {
++ int failures = 0;
++
++ for (int curr = getVolatile(array, index);;++failures) {
++ for (int i = 0; i < failures; ++i) {
++ ConcurrentUtil.backoff();
++ }
++
++ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, (int) (curr | param)))) {
++ return curr;
++ }
++ }
++ }
++
++ public static int getAndXorVolatileContended(final int[] array, final int index, final int param) {
++ int failures = 0;
++
++ for (int curr = getVolatile(array, index);;++failures) {
++ for (int i = 0; i < failures; ++i) {
++ ConcurrentUtil.backoff();
++ }
++
++ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, (int) (curr ^ param)))) {
++ return curr;
++ }
++ }
++ }
++
++ public static int getAndSetVolatileContended(final int[] array, final int index, final int param) {
++ int failures = 0;
++
++ for (int curr = getVolatile(array, index);;++failures) {
++ for (int i = 0; i < failures; ++i) {
++ ConcurrentUtil.backoff();
++ }
++
++ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, param))) {
++ return curr;
++ }
++ }
++ }
++
++ /* long array */
++
++ public static long getPlain(final long[] array, final int index) {
++ return (long)LONG_ARRAY_HANDLE.get(array, index);
++ }
++
++ public static long getOpaque(final long[] array, final int index) {
++ return (long)LONG_ARRAY_HANDLE.getOpaque(array, index);
++ }
++
++ public static long getAcquire(final long[] array, final int index) {
++ return (long)LONG_ARRAY_HANDLE.getAcquire(array, index);
++ }
++
++ public static long getVolatile(final long[] array, final int index) {
++ return (long)LONG_ARRAY_HANDLE.getVolatile(array, index);
++ }
++
++ public static void setPlain(final long[] array, final int index, final long value) {
++ LONG_ARRAY_HANDLE.set(array, index, value);
++ }
++
++ public static void setOpaque(final long[] array, final int index, final long value) {
++ LONG_ARRAY_HANDLE.setOpaque(array, index, value);
++ }
++
++ public static void setRelease(final long[] array, final int index, final long value) {
++ LONG_ARRAY_HANDLE.setRelease(array, index, value);
++ }
++
++ public static void setVolatile(final long[] array, final int index, final long value) {
++ LONG_ARRAY_HANDLE.setVolatile(array, index, value);
++ }
++
++ public static void setVolatileContended(final long[] array, final int index, final long param) {
++ int failures = 0;
++
++ for (long curr = getVolatile(array, index);;++failures) {
++ for (int i = 0; i < failures; ++i) {
++ ConcurrentUtil.backoff();
++ }
++
++ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, param))) {
++ return;
++ }
++ }
++ }
++
++ public static long compareAndExchangeVolatile(final long[] array, final int index, final long expect, final long update) {
++ return (long)LONG_ARRAY_HANDLE.compareAndExchange(array, index, expect, update);
++ }
++
++ public static long getAndAddVolatile(final long[] array, final int index, final long param) {
++ return (long)LONG_ARRAY_HANDLE.getAndAdd(array, index, param);
++ }
++
++ public static long getAndAndVolatile(final long[] array, final int index, final long param) {
++ return (long)LONG_ARRAY_HANDLE.getAndBitwiseAnd(array, index, param);
++ }
++
++ public static long getAndOrVolatile(final long[] array, final int index, final long param) {
++ return (long)LONG_ARRAY_HANDLE.getAndBitwiseOr(array, index, param);
++ }
++
++ public static long getAndXorVolatile(final long[] array, final int index, final long param) {
++ return (long)LONG_ARRAY_HANDLE.getAndBitwiseXor(array, index, param);
++ }
++
++ public static long getAndSetVolatile(final long[] array, final int index, final long param) {
++ return (long)LONG_ARRAY_HANDLE.getAndSet(array, index, param);
++ }
++
++ public static long compareAndExchangeVolatileContended(final long[] array, final int index, final long expect, final long update) {
++ return (long)LONG_ARRAY_HANDLE.compareAndExchange(array, index, expect, update);
++ }
++
++ public static long getAndAddVolatileContended(final long[] array, final int index, final long param) {
++ int failures = 0;
++
++ for (long curr = getVolatile(array, index);;++failures) {
++ for (int i = 0; i < failures; ++i) {
++ ConcurrentUtil.backoff();
++ }
++
++ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, (long) (curr + param)))) {
++ return curr;
++ }
++ }
++ }
++
++ public static long getAndAndVolatileContended(final long[] array, final int index, final long param) {
++ int failures = 0;
++
++ for (long curr = getVolatile(array, index);;++failures) {
++ for (int i = 0; i < failures; ++i) {
++ ConcurrentUtil.backoff();
++ }
++
++ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, (long) (curr & param)))) {
++ return curr;
++ }
++ }
++ }
++
++ public static long getAndOrVolatileContended(final long[] array, final int index, final long param) {
++ int failures = 0;
++
++ for (long curr = getVolatile(array, index);;++failures) {
++ for (int i = 0; i < failures; ++i) {
++ ConcurrentUtil.backoff();
++ }
++
++ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, (long) (curr | param)))) {
++ return curr;
++ }
++ }
++ }
++
++ public static long getAndXorVolatileContended(final long[] array, final int index, final long param) {
++ int failures = 0;
++
++ for (long curr = getVolatile(array, index);;++failures) {
++ for (int i = 0; i < failures; ++i) {
++ ConcurrentUtil.backoff();
++ }
++
++ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, (long) (curr ^ param)))) {
++ return curr;
++ }
++ }
++ }
++
++ public static long getAndSetVolatileContended(final long[] array, final int index, final long param) {
++ int failures = 0;
++
++ for (long curr = getVolatile(array, index);;++failures) {
++ for (int i = 0; i < failures; ++i) {
++ ConcurrentUtil.backoff();
++ }
++
++ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, param))) {
++ return curr;
++ }
++ }
++ }
++
++ /* boolean array */
++
++ public static boolean getPlain(final boolean[] array, final int index) {
++ return (boolean)BOOLEAN_ARRAY_HANDLE.get(array, index);
++ }
++
++ public static boolean getOpaque(final boolean[] array, final int index) {
++ return (boolean)BOOLEAN_ARRAY_HANDLE.getOpaque(array, index);
++ }
++
++ public static boolean getAcquire(final boolean[] array, final int index) {
++ return (boolean)BOOLEAN_ARRAY_HANDLE.getAcquire(array, index);
++ }
++
++ public static boolean getVolatile(final boolean[] array, final int index) {
++ return (boolean)BOOLEAN_ARRAY_HANDLE.getVolatile(array, index);
++ }
++
++ public static void setPlain(final boolean[] array, final int index, final boolean value) {
++ BOOLEAN_ARRAY_HANDLE.set(array, index, value);
++ }
++
++ public static void setOpaque(final boolean[] array, final int index, final boolean value) {
++ BOOLEAN_ARRAY_HANDLE.setOpaque(array, index, value);
++ }
++
++ public static void setRelease(final boolean[] array, final int index, final boolean value) {
++ BOOLEAN_ARRAY_HANDLE.setRelease(array, index, value);
++ }
++
++ public static void setVolatile(final boolean[] array, final int index, final boolean value) {
++ BOOLEAN_ARRAY_HANDLE.setVolatile(array, index, value);
++ }
++
++ public static void setVolatileContended(final boolean[] array, final int index, final boolean param) {
++ int failures = 0;
++
++ for (boolean curr = getVolatile(array, index);;++failures) {
++ for (int i = 0; i < failures; ++i) {
++ ConcurrentUtil.backoff();
++ }
++
++ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, param))) {
++ return;
++ }
++ }
++ }
++
++ public static boolean compareAndExchangeVolatile(final boolean[] array, final int index, final boolean expect, final boolean update) {
++ return (boolean)BOOLEAN_ARRAY_HANDLE.compareAndExchange(array, index, expect, update);
++ }
++
++ public static boolean getAndOrVolatile(final boolean[] array, final int index, final boolean param) {
++ return (boolean)BOOLEAN_ARRAY_HANDLE.getAndBitwiseOr(array, index, param);
++ }
++
++ public static boolean getAndXorVolatile(final boolean[] array, final int index, final boolean param) {
++ return (boolean)BOOLEAN_ARRAY_HANDLE.getAndBitwiseXor(array, index, param);
++ }
++
++ public static boolean getAndSetVolatile(final boolean[] array, final int index, final boolean param) {
++ return (boolean)BOOLEAN_ARRAY_HANDLE.getAndSet(array, index, param);
++ }
++
++ public static boolean compareAndExchangeVolatileContended(final boolean[] array, final int index, final boolean expect, final boolean update) {
++ return (boolean)BOOLEAN_ARRAY_HANDLE.compareAndExchange(array, index, expect, update);
++ }
++
++ public static boolean getAndAndVolatileContended(final boolean[] array, final int index, final boolean param) {
++ int failures = 0;
++
++ for (boolean curr = getVolatile(array, index);;++failures) {
++ for (int i = 0; i < failures; ++i) {
++ ConcurrentUtil.backoff();
++ }
++
++ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, (boolean) (curr & param)))) {
++ return curr;
++ }
++ }
++ }
++
++ public static boolean getAndOrVolatileContended(final boolean[] array, final int index, final boolean param) {
++ int failures = 0;
++
++ for (boolean curr = getVolatile(array, index);;++failures) {
++ for (int i = 0; i < failures; ++i) {
++ ConcurrentUtil.backoff();
++ }
++
++ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, (boolean) (curr | param)))) {
++ return curr;
++ }
++ }
++ }
++
++ public static boolean getAndXorVolatileContended(final boolean[] array, final int index, final boolean param) {
++ int failures = 0;
++
++ for (boolean curr = getVolatile(array, index);;++failures) {
++ for (int i = 0; i < failures; ++i) {
++ ConcurrentUtil.backoff();
++ }
++
++ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, (boolean) (curr ^ param)))) {
++ return curr;
++ }
++ }
++ }
++
++ public static boolean getAndSetVolatileContended(final boolean[] array, final int index, final boolean param) {
++ int failures = 0;
++
++ for (boolean curr = getVolatile(array, index);;++failures) {
++ for (int i = 0; i < failures; ++i) {
++ ConcurrentUtil.backoff();
++ }
++
++ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, param))) {
++ return curr;
++ }
++ }
++ }
++
++ @SuppressWarnings("unchecked")
++ public static <T> T getPlain(final T[] array, final int index) {
++ final Object ret = OBJECT_ARRAY_HANDLE.get((Object[])array, index);
++ return (T)ret;
++ }
++
++ @SuppressWarnings("unchecked")
++ public static <T> T getOpaque(final T[] array, final int index) {
++ final Object ret = OBJECT_ARRAY_HANDLE.getOpaque((Object[])array, index);
++ return (T)ret;
++ }
++
++ @SuppressWarnings("unchecked")
++ public static <T> T getAcquire(final T[] array, final int index) {
++ final Object ret = OBJECT_ARRAY_HANDLE.getAcquire((Object[])array, index);
++ return (T)ret;
++ }
++
++ @SuppressWarnings("unchecked")
++ public static <T> T getVolatile(final T[] array, final int index) {
++ final Object ret = OBJECT_ARRAY_HANDLE.getVolatile((Object[])array, index);
++ return (T)ret;
++ }
++
++ public static <T> void setPlain(final T[] array, final int index, final T value) {
++ OBJECT_ARRAY_HANDLE.set((Object[])array, index, (Object)value);
++ }
++
++ public static <T> void setOpaque(final T[] array, final int index, final T value) {
++ OBJECT_ARRAY_HANDLE.setOpaque((Object[])array, index, (Object)value);
++ }
++
++ public static <T> void setRelease(final T[] array, final int index, final T value) {
++ OBJECT_ARRAY_HANDLE.setRelease((Object[])array, index, (Object)value);
++ }
++
++ public static <T> void setVolatile(final T[] array, final int index, final T value) {
++ OBJECT_ARRAY_HANDLE.setVolatile((Object[])array, index, (Object)value);
++ }
++
++ public static <T> void setVolatileContended(final T[] array, final int index, final T param) {
++ int failures = 0;
++
++ for (T curr = getVolatile(array, index);;++failures) {
++ for (int i = 0; i < failures; ++i) {
++ ConcurrentUtil.backoff();
++ }
++
++ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, param))) {
++ return;
++ }
++ }
++ }
++
++ @SuppressWarnings("unchecked")
++ public static <T> T compareAndExchangeVolatile(final T[] array, final int index, final T expect, final T update) {
++ final Object ret = OBJECT_ARRAY_HANDLE.compareAndExchange((Object[])array, index, (Object)expect, (Object)update);
++ return (T)ret;
++ }
++
++ @SuppressWarnings("unchecked")
++ public static <T> T getAndSetVolatile(final T[] array, final int index, final T param) {
++ final Object ret = BYTE_ARRAY_HANDLE.getAndSet((Object[])array, index, (Object)param);
++ return (T)ret;
++ }
++
++ @SuppressWarnings("unchecked")
++ public static <T> T compareAndExchangeVolatileContended(final T[] array, final int index, final T expect, final T update) {
++ final Object ret = OBJECT_ARRAY_HANDLE.compareAndExchange((Object[])array, index, (Object)expect, (Object)update);
++ return (T)ret;
++ }
++
++ public static <T> T getAndSetVolatileContended(final T[] array, final int index, final T param) {
++ int failures = 0;
++
++ for (T curr = getVolatile(array, index);;++failures) {
++ for (int i = 0; i < failures; ++i) {
++ ConcurrentUtil.backoff();
++ }
++
++ if (curr == (curr = compareAndExchangeVolatileContended(array, index, curr, param))) {
++ return curr;
++ }
++ }
++ }
++}
+diff --git a/src/main/java/ca/spottedleaf/concurrentutil/util/CollectionUtil.java b/src/main/java/ca/spottedleaf/concurrentutil/util/CollectionUtil.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..9420b9822de99d3a31224642452835b0c986f7b4
+--- /dev/null
++++ b/src/main/java/ca/spottedleaf/concurrentutil/util/CollectionUtil.java
+@@ -0,0 +1,31 @@
++package ca.spottedleaf.concurrentutil.util;
++
++import java.util.Collection;
++
++public final class CollectionUtil {
++
++ public static String toString(final Collection<?> collection, final String name) {
++ return CollectionUtil.toString(collection, name, new StringBuilder(name.length() + 128)).toString();
++ }
++
++ public static StringBuilder toString(final Collection<?> collection, final String name, final StringBuilder builder) {
++ builder.append(name).append("{elements={");
++
++ boolean first = true;
++
++ for (final Object element : collection) {
++ if (!first) {
++ builder.append(", ");
++ }
++ first = false;
++
++ builder.append('"').append(element).append('"');
++ }
++
++ return builder.append("}}");
++ }
++
++ private CollectionUtil() {
++ throw new RuntimeException();
++ }
++}
+diff --git a/src/main/java/ca/spottedleaf/concurrentutil/util/ConcurrentUtil.java b/src/main/java/ca/spottedleaf/concurrentutil/util/ConcurrentUtil.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..23ae82e55696a7e2ff0e0f9609c0df6a48bb8d1d
+--- /dev/null
++++ b/src/main/java/ca/spottedleaf/concurrentutil/util/ConcurrentUtil.java
+@@ -0,0 +1,166 @@
++package ca.spottedleaf.concurrentutil.util;
++
++import java.lang.invoke.MethodHandles;
++import java.lang.invoke.VarHandle;
++import java.util.concurrent.locks.LockSupport;
++
++public final class ConcurrentUtil {
++
++ public static String genericToString(final Object object) {
++ return object == null ? "null" : object.getClass().getName() + ":" + object.hashCode() + ":" + object.toString();
++ }
++
++ public static void rethrow(Throwable exception) {
++ rethrow0(exception);
++ }
++
++ private static <T extends Throwable> void rethrow0(Throwable thr) throws T {
++ throw (T)thr;
++ }
++
++ public static VarHandle getVarHandle(final Class<?> lookIn, final String fieldName, final Class<?> fieldType) {
++ try {
++ return MethodHandles.privateLookupIn(lookIn, MethodHandles.lookup()).findVarHandle(lookIn, fieldName, fieldType);
++ } catch (final Exception ex) {
++ throw new RuntimeException(ex); // unreachable
++ }
++ }
++
++ public static VarHandle getStaticVarHandle(final Class<?> lookIn, final String fieldName, final Class<?> fieldType) {
++ try {
++ return MethodHandles.privateLookupIn(lookIn, MethodHandles.lookup()).findStaticVarHandle(lookIn, fieldName, fieldType);
++ } catch (final Exception ex) {
++ throw new RuntimeException(ex); // unreachable
++ }
++ }
++
++ /**
++ * Non-exponential backoff algorithm to use in lightly contended areas.
++ * @see ConcurrentUtil#exponentiallyBackoffSimple(long)
++ * @see ConcurrentUtil#exponentiallyBackoffComplex(long)
++ */
++ public static void backoff() {
++ Thread.onSpinWait();
++ }
++
++ /**
++ * Backoff algorithm to use for a short held lock (i.e compareAndExchange operation). Generally this should not be
++ * used when a thread can block another thread. Instead, use {@link ConcurrentUtil#exponentiallyBackoffComplex(long)}.
++ * @param counter The current counter.
++ * @return The counter plus 1.
++ * @see ConcurrentUtil#backoff()
++ * @see ConcurrentUtil#exponentiallyBackoffComplex(long)
++ */
++ public static long exponentiallyBackoffSimple(final long counter) {
++ for (long i = 0; i < counter; ++i) {
++ backoff();
++ }
++ return counter + 1L;
++ }
++
++ /**
++ * Backoff algorithm to use for a lock that can block other threads (i.e if another thread contending with this thread
++ * can be thrown off the scheduler). This lock should not be used for simple locks such as compareAndExchange.
++ * @param counter The current counter.
++ * @return The next (if any) step in the backoff logic.
++ * @see ConcurrentUtil#backoff()
++ * @see ConcurrentUtil#exponentiallyBackoffSimple(long)
++ */
++ public static long exponentiallyBackoffComplex(final long counter) {
++ // TODO experimentally determine counters
++ if (counter < 100L) {
++ return exponentiallyBackoffSimple(counter);
++ }
++ if (counter < 1_200L) {
++ Thread.yield();
++ LockSupport.parkNanos(1_000L);
++ return counter + 1L;
++ }
++ // scale 0.1ms (100us) per failure
++ Thread.yield();
++ LockSupport.parkNanos(100_000L * counter);
++ return counter + 1;
++ }
++
++ /**
++ * Simple exponential backoff that will linearly increase the time per failure, according to the scale.
++ * @param counter The current failure counter.
++ * @param scale Time per failure, in ns.
++ * @param max The maximum time to wait for, in ns.
++ * @return The next counter.
++ */
++ public static long linearLongBackoff(long counter, final long scale, long max) {
++ counter = Math.min(Long.MAX_VALUE, counter + 1); // prevent overflow
++ max = Math.max(0, max);
++
++ if (scale <= 0L) {
++ return counter;
++ }
++
++ long time = scale * counter;
++
++ if (time > max || time / scale != counter) {
++ time = max;
++ }
++
++ boolean interrupted = Thread.interrupted();
++ if (time > 1_000_000L) { // 1ms
++ Thread.yield();
++ }
++ LockSupport.parkNanos(time);
++ if (interrupted) {
++ Thread.currentThread().interrupt();
++ }
++ return counter;
++ }
++
++ /**
++ * Simple exponential backoff that will linearly increase the time per failure, according to the scale.
++ * @param counter The current failure counter.
++ * @param scale Time per failure, in ns.
++ * @param max The maximum time to wait for, in ns.
++ * @param deadline The deadline in ns. Deadline time source: {@link System#nanoTime()}.
++ * @return The next counter.
++ */
++ public static long linearLongBackoffDeadline(long counter, final long scale, long max, long deadline) {
++ counter = Math.min(Long.MAX_VALUE, counter + 1); // prevent overflow
++ max = Math.max(0, max);
++
++ if (scale <= 0L) {
++ return counter;
++ }
++
++ long time = scale * counter;
++
++ // check overflow
++ if (time / scale != counter) {
++ // overflew
++ --counter;
++ time = max;
++ } else if (time > max) {
++ time = max;
++ }
++
++ final long currTime = System.nanoTime();
++ final long diff = deadline - currTime;
++ if (diff <= 0) {
++ return counter;
++ }
++ if (diff <= 1_500_000L) { // 1.5ms
++ time = 100_000L; // 100us
++ } else if (time > 1_000_000L) { // 1ms
++ Thread.yield();
++ }
++
++ boolean interrupted = Thread.interrupted();
++ LockSupport.parkNanos(time);
++ if (interrupted) {
++ Thread.currentThread().interrupt();
++ }
++ return counter;
++ }
++
++ public static VarHandle getArrayHandle(final Class<?> type) {
++ return MethodHandles.arrayElementVarHandle(type);
++ }
++}
+diff --git a/src/main/java/ca/spottedleaf/concurrentutil/util/Validate.java b/src/main/java/ca/spottedleaf/concurrentutil/util/Validate.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..382177d0d162fa3139c9078a873ce2504a2b17b2
+--- /dev/null
++++ b/src/main/java/ca/spottedleaf/concurrentutil/util/Validate.java
+@@ -0,0 +1,28 @@
++package ca.spottedleaf.concurrentutil.util;
++
++public final class Validate {
++
++ public static <T> T notNull(final T obj) {
++ if (obj == null) {
++ throw new NullPointerException();
++ }
++ return obj;
++ }
++
++ public static <T> T notNull(final T obj, final String msgIfNull) {
++ if (obj == null) {
++ throw new NullPointerException(msgIfNull);
++ }
++ return obj;
++ }
++
++ public static void arrayBounds(final int off, final int len, final int arrayLength, final String msgPrefix) {
++ if (off < 0 || len < 0 || (arrayLength - off) < len) {
++ throw new ArrayIndexOutOfBoundsException(msgPrefix + ": off: " + off + ", len: " + len + ", array length: " + arrayLength);
++ }
++ }
++
++ private Validate() {
++ throw new RuntimeException();
++ }
++}
diff --git a/patches/server/0006-CB-fixes.patch b/patches/server/0007-CB-fixes.patch
index b5c9b287e2..e0daaa9d40 100644
--- a/patches/server/0006-CB-fixes.patch
+++ b/patches/server/0007-CB-fixes.patch
@@ -17,7 +17,7 @@ Subject: [PATCH] CB fixes
Co-authored-by: Spottedleaf <[email protected]>
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index 1a23437b9fa17846fd28163ae930d21a6bb00138..4f1e8d36c363eb74e8f1e593f35a7bb8550f8918 100644
+index bbdde701a16480b0b4b29e8fb6b5b5d987db0ce3..aa396df025115c7fd866cbc63a44c2c17abfde84 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -293,7 +293,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
@@ -67,7 +67,7 @@ index 9998e1c94b72b90dd3ba4bcce1b4b3653b9b1b2b..963ad3ce1ef83888ae1537ff01accdbb
this.registryAccess = registryManager;
this.structureTemplateManager = structureTemplateManager;
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-index 3620b8a76b5c13d33ec32e4a0d7fc7fa7290f220..5550dbea555a99ee1612609093292db79a625c94 100644
+index 7c3d02a8a3bac227692ad2349981bc8c6c600341..4dd952faac05f553b28d1252296b0587369865f4 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -2278,7 +2278,13 @@ public final class CraftServer implements Server {
diff --git a/patches/server/0007-MC-Utils.patch b/patches/server/0008-MC-Utils.patch
index 271f065ad0..2d9248eb2a 100644
--- a/patches/server/0007-MC-Utils.patch
+++ b/patches/server/0008-MC-Utils.patch
@@ -4528,9 +4528,284 @@ index 207f1c1fc9d4451d27047bb8362bded8cd53e32f..021a26a6b1c258deffc26c035ab52a4e
if (packet.isSkippable()) {
throw new SkipPacketException(var10);
} else {
+diff --git a/src/main/java/net/minecraft/server/ChunkSystem.java b/src/main/java/net/minecraft/server/ChunkSystem.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..83dc09f6526206690c474b50a7a6e71cefc93ab4
+--- /dev/null
++++ b/src/main/java/net/minecraft/server/ChunkSystem.java
+@@ -0,0 +1,269 @@
++package net.minecraft.server;
++
++import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor;
++import com.destroystokyo.paper.util.SneakyThrow;
++import com.mojang.datafixers.util.Either;
++import com.mojang.logging.LogUtils;
++import io.papermc.paper.util.CoordinateUtils;
++import net.minecraft.server.level.ChunkHolder;
++import net.minecraft.server.level.ChunkMap;
++import net.minecraft.server.level.ServerLevel;
++import net.minecraft.server.level.TicketType;
++import net.minecraft.world.entity.Entity;
++import net.minecraft.world.level.ChunkPos;
++import net.minecraft.world.level.chunk.ChunkAccess;
++import net.minecraft.world.level.chunk.ChunkStatus;
++import net.minecraft.world.level.chunk.LevelChunk;
++import org.bukkit.Bukkit;
++import org.slf4j.Logger;
++import java.util.ArrayList;
++import java.util.List;
++import java.util.concurrent.CompletableFuture;
++import java.util.function.Consumer;
++
++public final class ChunkSystem {
++
++ private static final Logger LOGGER = LogUtils.getLogger();
++
++ public static void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run) {
++ scheduleChunkTask(level, chunkX, chunkZ, run, PrioritisedExecutor.Priority.NORMAL);
++ }
++
++ public static void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run, final PrioritisedExecutor.Priority priority) {
++ level.chunkSource.mainThreadProcessor.execute(run);
++ }
++
++ public static void scheduleChunkLoad(final ServerLevel level, final int chunkX, final int chunkZ, final boolean gen,
++ final ChunkStatus toStatus, final boolean addTicket, final PrioritisedExecutor.Priority priority,
++ final Consumer<ChunkAccess> onComplete) {
++ if (gen) {
++ scheduleChunkLoad(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete);
++ return;
++ }
++ scheduleChunkLoad(level, chunkX, chunkZ, ChunkStatus.EMPTY, addTicket, priority, (final ChunkAccess chunk) -> {
++ if (chunk == null) {
++ onComplete.accept(null);
++ } else {
++ if (chunk.getStatus().isOrAfter(toStatus)) {
++ scheduleChunkLoad(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete);
++ } else {
++ onComplete.accept(null);
++ }
++ }
++ });
++ }
++
++ static final TicketType<Long> CHUNK_LOAD = TicketType.create("chunk_load", Long::compareTo);
++
++ private static long chunkLoadCounter = 0L;
++ public static void scheduleChunkLoad(final ServerLevel level, final int chunkX, final int chunkZ, final ChunkStatus toStatus,
++ final boolean addTicket, final PrioritisedExecutor.Priority priority, final Consumer<ChunkAccess> onComplete) {
++ if (!Bukkit.isPrimaryThread()) {
++ scheduleChunkTask(level, chunkX, chunkZ, () -> {
++ scheduleChunkLoad(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete);
++ }, priority);
++ return;
++ }
++
++ final int minLevel = 33 + ChunkStatus.getDistance(toStatus);
++ final Long chunkReference = addTicket ? Long.valueOf(++chunkLoadCounter) : null;
++ final ChunkPos chunkPos = new ChunkPos(chunkX, chunkZ);
++
++ if (addTicket) {
++ level.chunkSource.addTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel, chunkReference);
++ }
++ level.chunkSource.runDistanceManagerUpdates();
++
++ final Consumer<ChunkAccess> loadCallback = (final ChunkAccess chunk) -> {
++ try {
++ if (onComplete != null) {
++ onComplete.accept(chunk);
++ }
++ } catch (final ThreadDeath death) {
++ throw death;
++ } catch (final Throwable thr) {
++ LOGGER.error("Exception handling chunk load callback", thr);
++ SneakyThrow.sneaky(thr);
++ } finally {
++ if (addTicket) {
++ level.chunkSource.addTicketAtLevel(TicketType.UNKNOWN, chunkPos, minLevel, chunkPos);
++ level.chunkSource.removeTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel, chunkReference);
++ }
++ }
++ };
++
++ final ChunkHolder holder = level.chunkSource.chunkMap.getUpdatingChunkIfPresent(CoordinateUtils.getChunkKey(chunkX, chunkZ));
++
++ if (holder == null || holder.getTicketLevel() > minLevel) {
++ loadCallback.accept(null);
++ return;
++ }
++
++ final CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> loadFuture = holder.getOrScheduleFuture(toStatus, level.chunkSource.chunkMap);
++
++ if (loadFuture.isDone()) {
++ loadCallback.accept(loadFuture.join().left().orElse(null));
++ return;
++ }
++
++ loadFuture.whenCompleteAsync((final Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure> either, final Throwable thr) -> {
++ if (thr != null) {
++ loadCallback.accept(null);
++ return;
++ }
++ loadCallback.accept(either.left().orElse(null));
++ }, (final Runnable r) -> {
++ scheduleChunkTask(level, chunkX, chunkZ, r, PrioritisedExecutor.Priority.HIGHEST);
++ });
++ }
++
++ public static void scheduleTickingState(final ServerLevel level, final int chunkX, final int chunkZ,
++ final ChunkHolder.FullChunkStatus toStatus, final boolean addTicket,
++ final PrioritisedExecutor.Priority priority, final Consumer<LevelChunk> onComplete) {
++ if (toStatus == ChunkHolder.FullChunkStatus.INACCESSIBLE) {
++ throw new IllegalArgumentException("Cannot wait for INACCESSIBLE status");
++ }
++
++ if (!Bukkit.isPrimaryThread()) {
++ scheduleChunkTask(level, chunkX, chunkZ, () -> {
++ scheduleTickingState(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete);
++ }, priority);
++ return;
++ }
++
++ final int minLevel = 33 - (toStatus.ordinal() - 1);
++ final int radius = toStatus.ordinal() - 1;
++ final Long chunkReference = addTicket ? Long.valueOf(++chunkLoadCounter) : null;
++ final ChunkPos chunkPos = new ChunkPos(chunkX, chunkZ);
++
++ if (addTicket) {
++ level.chunkSource.addTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel, chunkReference);
++ }
++ level.chunkSource.runDistanceManagerUpdates();
++
++ final Consumer<LevelChunk> loadCallback = (final LevelChunk chunk) -> {
++ try {
++ if (onComplete != null) {
++ onComplete.accept(chunk);
++ }
++ } catch (final ThreadDeath death) {
++ throw death;
++ } catch (final Throwable thr) {
++ LOGGER.error("Exception handling chunk load callback", thr);
++ SneakyThrow.sneaky(thr);
++ } finally {
++ if (addTicket) {
++ level.chunkSource.addTicketAtLevel(TicketType.UNKNOWN, chunkPos, minLevel, chunkPos);
++ level.chunkSource.removeTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel, chunkReference);
++ }
++ }
++ };
++
++ final ChunkHolder holder = level.chunkSource.chunkMap.getUpdatingChunkIfPresent(CoordinateUtils.getChunkKey(chunkX, chunkZ));
++
++ if (holder == null || holder.getTicketLevel() > minLevel) {
++ loadCallback.accept(null);
++ return;
++ }
++
++ final CompletableFuture<Either<LevelChunk, ChunkHolder.ChunkLoadingFailure>> tickingState;
++ switch (toStatus) {
++ case BORDER: {
++ tickingState = holder.getFullChunkFuture();
++ break;
++ }
++ case TICKING: {
++ tickingState = holder.getTickingChunkFuture();
++ break;
++ }
++ case ENTITY_TICKING: {
++ tickingState = holder.getEntityTickingChunkFuture();
++ break;
++ }
++ default: {
++ throw new IllegalStateException("Cannot reach here");
++ }
++ }
++
++ if (tickingState.isDone()) {
++ loadCallback.accept(tickingState.join().left().orElse(null));
++ return;
++ }
++
++ tickingState.whenCompleteAsync((final Either<LevelChunk, ChunkHolder.ChunkLoadingFailure> either, final Throwable thr) -> {
++ if (thr != null) {
++ loadCallback.accept(null);
++ return;
++ }
++ loadCallback.accept(either.left().orElse(null));
++ }, (final Runnable r) -> {
++ scheduleChunkTask(level, chunkX, chunkZ, r, PrioritisedExecutor.Priority.HIGHEST);
++ });
++ }
++
++ public static List<ChunkHolder> getVisibleChunkHolders(final ServerLevel level) {
++ return new ArrayList<>(level.chunkSource.chunkMap.visibleChunkMap.values());
++ }
++
++ public static List<ChunkHolder> getUpdatingChunkHolders(final ServerLevel level) {
++ return new ArrayList<>(level.chunkSource.chunkMap.updatingChunkMap.values());
++ }
++
++ public static int getVisibleChunkHolderCount(final ServerLevel level) {
++ return level.chunkSource.chunkMap.visibleChunkMap.size();
++ }
++
++ public static int getUpdatingChunkHolderCount(final ServerLevel level) {
++ return level.chunkSource.chunkMap.updatingChunkMap.size();
++ }
++
++ public static boolean hasAnyChunkHolders(final ServerLevel level) {
++ return getUpdatingChunkHolderCount(level) != 0;
++ }
++
++ public static void onEntityPreAdd(final ServerLevel level, final Entity entity) {
++
++ }
++
++ public static void onChunkHolderCreate(final ServerLevel level, final ChunkHolder holder) {
++ final ChunkMap chunkMap = level.chunkSource.chunkMap;
++ for (int index = 0, len = chunkMap.regionManagers.size(); index < len; ++index) {
++ chunkMap.regionManagers.get(index).addChunk(holder.pos.x, holder.pos.z);
++ }
++ }
++
++ public static void onChunkHolderDelete(final ServerLevel level, final ChunkHolder holder) {
++ final ChunkMap chunkMap = level.chunkSource.chunkMap;
++ for (int index = 0, len = chunkMap.regionManagers.size(); index < len; ++index) {
++ chunkMap.regionManagers.get(index).removeChunk(holder.pos.x, holder.pos.z);
++ }
++ }
++
++ public static void onChunkBorder(LevelChunk chunk, ChunkHolder holder) {
++ chunk.playerChunk = holder;
++ }
++
++ public static void onChunkNotBorder(LevelChunk chunk, ChunkHolder holder) {
++
++ }
++
++ public static void onChunkTicking(LevelChunk chunk, ChunkHolder holder) {
++ chunk.level.getChunkSource().tickingChunks.add(chunk);
++ }
++
++ public static void onChunkNotTicking(LevelChunk chunk, ChunkHolder holder) {
++ chunk.level.getChunkSource().tickingChunks.remove(chunk);
++ }
++
++ public static void onChunkEntityTicking(LevelChunk chunk, ChunkHolder holder) {
++ chunk.level.getChunkSource().entityTickingChunks.add(chunk);
++ }
++
++ public static void onChunkNotEntityTicking(LevelChunk chunk, ChunkHolder holder) {
++ chunk.level.getChunkSource().entityTickingChunks.remove(chunk);
++ }
++
++ private ChunkSystem() {
++ throw new RuntimeException();
++ }
++}
diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java
new file mode 100644
-index 0000000000000000000000000000000000000000..9f292deee1b793d52b5774304318e940128d1e26
+index 0000000000000000000000000000000000000000..b310d51b7fe3e8cef0a450674725969fe1ce78a4
--- /dev/null
+++ b/src/main/java/net/minecraft/server/MCUtil.java
@@ -0,0 +1,511 @@
@@ -4845,7 +5120,7 @@ index 0000000000000000000000000000000000000000..9f292deee1b793d52b5774304318e940
+ * @return
+ */
+ public static void ensureMain(String reason, Runnable run) {
-+ if (AsyncCatcher.enabled && Thread.currentThread() != MinecraftServer.getServer().serverThread) {
++ if (!isMainThread()) {
+ if (reason != null) {
+ new IllegalStateException("Asynchronous " + reason + "!").printStackTrace();
+ }
@@ -4870,7 +5145,7 @@ index 0000000000000000000000000000000000000000..9f292deee1b793d52b5774304318e940
+ * @return
+ */
+ public static <T> T ensureMain(String reason, Supplier<T> run) {
-+ if (AsyncCatcher.enabled && Thread.currentThread() != MinecraftServer.getServer().serverThread) {
++ if (!isMainThread()) {
+ if (reason != null) {
+ new IllegalStateException("Asynchronous " + reason + "! Blocking thread until it returns ").printStackTrace();
+ }
@@ -5046,7 +5321,7 @@ index 0000000000000000000000000000000000000000..9f292deee1b793d52b5774304318e940
+ }
+}
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
-index b7d44c4a961ad3881bbf8f87f1595be79e3467f6..3aadba90ab32388b9e8ef96f182fa263c760f53b 100644
+index 80a3c56fb5e73c09c542b17aac952fb63081a662..805a1773d55e2551911e5b8e69052e23f630359b 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -282,6 +282,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -5097,7 +5372,7 @@ index b7d44c4a961ad3881bbf8f87f1595be79e3467f6..3aadba90ab32388b9e8ef96f182fa263
} catch (Throwable throwable) {
// Spigot Start
diff --git a/src/main/java/net/minecraft/server/level/ChunkHolder.java b/src/main/java/net/minecraft/server/level/ChunkHolder.java
-index f902b1f7062fc2c81e0ce43e8b8599192469e57c..90fcb4dc89643b1c706ea4554595a842198558a1 100644
+index f902b1f7062fc2c81e0ce43e8b8599192469e57c..0873134f1f6de0c372ba28b89a20302c9a0115d8 100644
--- a/src/main/java/net/minecraft/server/level/ChunkHolder.java
+++ b/src/main/java/net/minecraft/server/level/ChunkHolder.java
@@ -52,9 +52,9 @@ public class ChunkHolder {
@@ -5113,16 +5388,26 @@ index f902b1f7062fc2c81e0ce43e8b8599192469e57c..90fcb4dc89643b1c706ea4554595a842
private CompletableFuture<ChunkAccess> chunkToSave;
@Nullable
private final DebugBuffer<ChunkHolder.ChunkSaveDebug> chunkToSaveHistory;
-@@ -73,6 +73,8 @@ public class ChunkHolder {
+@@ -73,6 +73,18 @@ public class ChunkHolder {
private boolean resendLight;
private CompletableFuture<Void> pendingFullStateConfirmation;
+ private final ChunkMap chunkMap; // Paper
+
++ // Paper start
++ public void onChunkAdd() {
++
++ }
++
++ public void onChunkRemove() {
++
++ }
++ // Paper end
++
public ChunkHolder(ChunkPos pos, int level, LevelHeightAccessor world, LevelLightEngine lightingProvider, ChunkHolder.LevelChangeListener levelUpdateListener, ChunkHolder.PlayerProvider playersWatchingChunkProvider) {
this.futures = new AtomicReferenceArray(ChunkHolder.CHUNK_STATUSES.size());
this.fullChunkFuture = ChunkHolder.UNLOADED_LEVEL_CHUNK_FUTURE;
-@@ -93,8 +95,23 @@ public class ChunkHolder {
+@@ -93,8 +105,23 @@ public class ChunkHolder {
this.queueLevel = this.oldTicketLevel;
this.setTicketLevel(level);
this.changedBlocksPerSection = new ShortSet[world.getSectionsCount()];
@@ -5146,7 +5431,7 @@ index f902b1f7062fc2c81e0ce43e8b8599192469e57c..90fcb4dc89643b1c706ea4554595a842
// CraftBukkit start
public LevelChunk getFullChunkNow() {
// Note: We use the oldTicketLevel for isLoaded checks.
-@@ -119,20 +136,20 @@ public class ChunkHolder {
+@@ -119,20 +146,20 @@ public class ChunkHolder {
return ChunkHolder.getStatus(this.ticketLevel).isOrAfter(leastStatus) ? this.getFutureIfPresentUnchecked(leastStatus) : ChunkHolder.UNLOADED_CHUNK_FUTURE;
}
@@ -5171,7 +5456,7 @@ index f902b1f7062fc2c81e0ce43e8b8599192469e57c..90fcb4dc89643b1c706ea4554595a842
CompletableFuture<Either<LevelChunk, ChunkHolder.ChunkLoadingFailure>> completablefuture = this.getTickingChunkFuture();
Either<LevelChunk, ChunkHolder.ChunkLoadingFailure> either = (Either) completablefuture.getNow(null); // CraftBukkit - decompile error
-@@ -140,7 +157,7 @@ public class ChunkHolder {
+@@ -140,7 +167,7 @@ public class ChunkHolder {
}
@Nullable
@@ -5180,7 +5465,7 @@ index f902b1f7062fc2c81e0ce43e8b8599192469e57c..90fcb4dc89643b1c706ea4554595a842
CompletableFuture<Either<LevelChunk, ChunkHolder.ChunkLoadingFailure>> completablefuture = this.getFullChunkFuture();
Either<LevelChunk, ChunkHolder.ChunkLoadingFailure> either = (Either) completablefuture.getNow(null); // CraftBukkit - decompile error
-@@ -161,6 +178,21 @@ public class ChunkHolder {
+@@ -161,6 +188,21 @@ public class ChunkHolder {
return null;
}
@@ -5202,7 +5487,7 @@ index f902b1f7062fc2c81e0ce43e8b8599192469e57c..90fcb4dc89643b1c706ea4554595a842
@Nullable
public ChunkAccess getLastAvailable() {
for (int i = ChunkHolder.CHUNK_STATUSES.size() - 1; i >= 0; --i) {
-@@ -179,7 +211,7 @@ public class ChunkHolder {
+@@ -179,7 +221,7 @@ public class ChunkHolder {
return null;
}
@@ -5211,7 +5496,7 @@ index f902b1f7062fc2c81e0ce43e8b8599192469e57c..90fcb4dc89643b1c706ea4554595a842
return this.chunkToSave;
}
-@@ -360,11 +392,11 @@ public class ChunkHolder {
+@@ -360,11 +402,11 @@ public class ChunkHolder {
return ChunkHolder.getFullChunkStatus(this.ticketLevel);
}
@@ -5225,7 +5510,7 @@ index f902b1f7062fc2c81e0ce43e8b8599192469e57c..90fcb4dc89643b1c706ea4554595a842
return this.ticketLevel;
}
-@@ -453,14 +485,27 @@ public class ChunkHolder {
+@@ -453,14 +495,31 @@ public class ChunkHolder {
this.wasAccessibleSinceLastSave |= flag3;
if (!flag2 && flag3) {
@@ -5236,16 +5521,20 @@ index f902b1f7062fc2c81e0ce43e8b8599192469e57c..90fcb4dc89643b1c706ea4554595a842
+ this.fullChunkFuture.thenAccept(either -> {
+ final Optional<LevelChunk> left = either.left();
+ if (left.isPresent() && ChunkHolder.this.fullChunkCreateCount == expectCreateCount) {
-+ // note: Here is a very good place to add callbacks to logic waiting on this.
+ LevelChunk fullChunk = either.left().get();
+ ChunkHolder.this.isFullChunkReady = true;
-+ fullChunk.playerChunk = ChunkHolder.this;
++ net.minecraft.server.ChunkSystem.onChunkBorder(fullChunk, this);
+ }
+ });
this.updateChunkToSave(this.fullChunkFuture, "full");
}
if (flag2 && !flag3) {
++ // Paper start
++ if (this.isFullChunkReady) {
++ net.minecraft.server.ChunkSystem.onChunkNotBorder(this.fullChunkFuture.join().left().get(), this); // Paper
++ }
++ // Paper end
this.fullChunkFuture.complete(ChunkHolder.UNLOADED_LEVEL_CHUNK);
this.fullChunkFuture = ChunkHolder.UNLOADED_LEVEL_CHUNK_FUTURE;
+ ++this.fullChunkCreateCount; // Paper - cache ticking ready status
@@ -5253,7 +5542,7 @@ index f902b1f7062fc2c81e0ce43e8b8599192469e57c..90fcb4dc89643b1c706ea4554595a842
}
boolean flag4 = playerchunk_state.isOrAfter(ChunkHolder.FullChunkStatus.TICKING);
-@@ -469,12 +514,29 @@ public class ChunkHolder {
+@@ -469,11 +528,25 @@ public class ChunkHolder {
if (!flag4 && flag5) {
this.tickingChunkFuture = chunkStorage.prepareTickingChunk(this);
this.scheduleFullChunkPromotion(chunkStorage, this.tickingChunkFuture, executor, ChunkHolder.FullChunkStatus.TICKING);
@@ -5262,9 +5551,7 @@ index f902b1f7062fc2c81e0ce43e8b8599192469e57c..90fcb4dc89643b1c706ea4554595a842
+ either.ifLeft(chunk -> {
+ // note: Here is a very good place to add callbacks to logic waiting on this.
+ ChunkHolder.this.isTickingReady = true;
-+ // Paper start - ticking chunk set
-+ ChunkHolder.this.chunkMap.level.getChunkSource().tickingChunks.add(chunk);
-+ // Paper end - ticking chunk set
++ net.minecraft.server.ChunkSystem.onChunkTicking(chunk, this);
+ });
+ });
+ // Paper end
@@ -5273,18 +5560,16 @@ index f902b1f7062fc2c81e0ce43e8b8599192469e57c..90fcb4dc89643b1c706ea4554595a842
if (flag4 && !flag5) {
- this.tickingChunkFuture.complete(ChunkHolder.UNLOADED_LEVEL_CHUNK);
++ // Paper start
++ if (this.isTickingReady) {
++ net.minecraft.server.ChunkSystem.onChunkNotTicking(this.tickingChunkFuture.join().left().get(), this); // Paper
++ }
++ // Paper end
+ this.tickingChunkFuture.complete(ChunkHolder.UNLOADED_LEVEL_CHUNK); this.isTickingReady = false; // Paper - cache chunk ticking stage
this.tickingChunkFuture = ChunkHolder.UNLOADED_LEVEL_CHUNK_FUTURE;
-+ // Paper start - ticking chunk set
-+ LevelChunk chunkIfCached = this.getFullChunkNowUnchecked();
-+ if (chunkIfCached != null) {
-+ this.chunkMap.level.getChunkSource().tickingChunks.remove(chunkIfCached);
-+ }
-+ // Paper end - ticking chunk set
}
- boolean flag6 = playerchunk_state.isOrAfter(ChunkHolder.FullChunkStatus.ENTITY_TICKING);
-@@ -487,12 +549,28 @@ public class ChunkHolder {
+@@ -487,11 +560,24 @@ public class ChunkHolder {
this.entityTickingChunkFuture = chunkStorage.prepareEntityTickingChunk(this.pos);
this.scheduleFullChunkPromotion(chunkStorage, this.entityTickingChunkFuture, executor, ChunkHolder.FullChunkStatus.ENTITY_TICKING);
@@ -5292,9 +5577,7 @@ index f902b1f7062fc2c81e0ce43e8b8599192469e57c..90fcb4dc89643b1c706ea4554595a842
+ this.entityTickingChunkFuture.thenAccept(either -> {
+ either.ifLeft(chunk -> {
+ ChunkHolder.this.isEntityTickingReady = true;
-+ // Paper start - entity ticking chunk set
-+ ChunkHolder.this.chunkMap.level.getChunkSource().entityTickingChunks.add(chunk);
-+ // Paper end - entity ticking chunk set
++ net.minecraft.server.ChunkSystem.onChunkEntityTicking(chunk, this);
+ });
+ });
+ // Paper end
@@ -5303,18 +5586,16 @@ index f902b1f7062fc2c81e0ce43e8b8599192469e57c..90fcb4dc89643b1c706ea4554595a842
if (flag6 && !flag7) {
- this.entityTickingChunkFuture.complete(ChunkHolder.UNLOADED_LEVEL_CHUNK);
++ // Paper start
++ if (this.isEntityTickingReady) {
++ net.minecraft.server.ChunkSystem.onChunkNotEntityTicking(this.entityTickingChunkFuture.join().left().get(), this);
++ }
++ // Paper end
+ this.entityTickingChunkFuture.complete(ChunkHolder.UNLOADED_LEVEL_CHUNK); this.isEntityTickingReady = false; // Paper - cache chunk ticking stage
this.entityTickingChunkFuture = ChunkHolder.UNLOADED_LEVEL_CHUNK_FUTURE;
-+ // Paper start - entity ticking chunk set
-+ LevelChunk chunkIfCached = this.getFullChunkNowUnchecked();
-+ if (chunkIfCached != null) {
-+ this.chunkMap.level.getChunkSource().entityTickingChunks.remove(chunkIfCached);
-+ }
-+ // Paper end - entity ticking chunk set
}
- if (!playerchunk_state1.isOrAfter(playerchunk_state)) {
-@@ -608,4 +686,18 @@ public class ChunkHolder {
+@@ -608,4 +694,18 @@ public class ChunkHolder {
}
};
}
@@ -5334,7 +5615,7 @@ index f902b1f7062fc2c81e0ce43e8b8599192469e57c..90fcb4dc89643b1c706ea4554595a842
+ // Paper end
}
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
-index 91a9b9ff0d7821a2261e7137fb1b3989ba096b88..6304a5b78ab1f3ef2478c7e2c493ebd760b5508e 100644
+index 91a9b9ff0d7821a2261e7137fb1b3989ba096b88..1fbe1b6de925f71763f79fe3d2371b70a8650f25 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -63,6 +63,7 @@ import net.minecraft.network.protocol.game.ClientboundSetChunkCacheCenterPacket;
@@ -5428,19 +5709,78 @@ index 91a9b9ff0d7821a2261e7137fb1b3989ba096b88..6304a5b78ab1f3ef2478c7e2c493ebd7
private CompletableFuture<Either<List<ChunkAccess>, ChunkHolder.ChunkLoadingFailure>> getChunkRangeFuture(ChunkPos centerChunk, int margin, IntFunction<ChunkStatus> distanceToStatus) {
List<CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>>> list = new ArrayList();
List<ChunkHolder> list1 = new ArrayList();
-@@ -442,6 +505,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -398,9 +461,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+ };
+
+ stringbuilder.append("Updating:").append(System.lineSeparator());
+- this.updatingChunkMap.values().forEach(consumer);
++ net.minecraft.server.ChunkSystem.getUpdatingChunkHolders(this.level).forEach(consumer); // Paper
+ stringbuilder.append("Visible:").append(System.lineSeparator());
+- this.visibleChunkMap.values().forEach(consumer);
++ net.minecraft.server.ChunkSystem.getVisibleChunkHolders(this.level).forEach(consumer); // Paper
+ CrashReport crashreport = CrashReport.forThrowable(exception, "Chunk loading");
+ CrashReportCategory crashreportsystemdetails = crashreport.addCategory("Chunk loading");
+
+@@ -442,8 +505,14 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
holder.setTicketLevel(level);
} else {
holder = new ChunkHolder(new ChunkPos(pos), level, this.level, this.lightEngine, this.queueSorter, this);
+ // Paper start
-+ for (int index = 0, len = this.regionManagers.size(); index < len; ++index) {
-+ this.regionManagers.get(index).addChunk(holder.pos.x, holder.pos.z);
-+ }
++ net.minecraft.server.ChunkSystem.onChunkHolderCreate(this.level, holder);
+ // Paper end
}
++ // Paper start
++ holder.onChunkAdd();
++ // Paper end
this.updatingChunkMap.put(pos, holder);
-@@ -559,7 +627,13 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+ this.modified = true;
+ }
+@@ -465,7 +534,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+
+ protected void saveAllChunks(boolean flush) {
+ if (flush) {
+- List<ChunkHolder> list = (List) this.visibleChunkMap.values().stream().filter(ChunkHolder::wasAccessibleSinceLastSave).peek(ChunkHolder::refreshAccessibility).collect(Collectors.toList());
++ List<ChunkHolder> list = (List) net.minecraft.server.ChunkSystem.getVisibleChunkHolders(this.level).stream().filter(ChunkHolder::wasAccessibleSinceLastSave).peek(ChunkHolder::refreshAccessibility).collect(Collectors.toList()); // Paper
+ MutableBoolean mutableboolean = new MutableBoolean();
+
+ do {
+@@ -494,7 +563,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+ });
+ this.flushWorker();
+ } else {
+- this.visibleChunkMap.values().forEach(this::saveChunkIfNeeded);
++ net.minecraft.server.ChunkSystem.getVisibleChunkHolders(this.level).forEach(this::saveChunkIfNeeded);
+ }
+
+ }
+@@ -513,7 +582,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+ }
+
+ public boolean hasWork() {
+- return this.lightEngine.hasLightWork() || !this.pendingUnloads.isEmpty() || !this.updatingChunkMap.isEmpty() || this.poiManager.hasWork() || !this.toDrop.isEmpty() || !this.unloadQueue.isEmpty() || this.queueSorter.hasWork() || this.distanceManager.hasTickets();
++ return this.lightEngine.hasLightWork() || !this.pendingUnloads.isEmpty() || net.minecraft.server.ChunkSystem.hasAnyChunkHolders(this.level) || this.poiManager.hasWork() || !this.toDrop.isEmpty() || !this.unloadQueue.isEmpty() || this.queueSorter.hasWork() || this.distanceManager.hasTickets(); // Paper
+ }
+
+ private void processUnloads(BooleanSupplier shouldKeepTicking) {
+@@ -524,6 +593,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+ ChunkHolder playerchunk = (ChunkHolder) this.updatingChunkMap.remove(j);
+
+ if (playerchunk != null) {
++ playerchunk.onChunkRemove(); // Paper
+ this.pendingUnloads.put(j, playerchunk);
+ this.modified = true;
+ ++i;
+@@ -541,7 +611,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+ }
+
+ int l = 0;
+- ObjectIterator objectiterator = this.visibleChunkMap.values().iterator();
++ Iterator objectiterator = net.minecraft.server.ChunkSystem.getVisibleChunkHolders(this.level).iterator(); // Paper
+
+ while (l < 20 && shouldKeepTicking.getAsBoolean() && objectiterator.hasNext()) {
+ if (this.saveChunkIfNeeded((ChunkHolder) objectiterator.next())) {
+@@ -559,7 +629,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
if (completablefuture1 != completablefuture) {
this.scheduleUnload(pos, holder);
} else {
@@ -5448,26 +5788,66 @@ index 91a9b9ff0d7821a2261e7137fb1b3989ba096b88..6304a5b78ab1f3ef2478c7e2c493ebd7
+ // Paper start
+ boolean removed;
+ if ((removed = this.pendingUnloads.remove(pos, holder)) && ichunkaccess != null) {
-+ for (int index = 0, len = this.regionManagers.size(); index < len; ++index) {
-+ this.regionManagers.get(index).removeChunk(holder.pos.x, holder.pos.z);
-+ }
++ net.minecraft.server.ChunkSystem.onChunkHolderDelete(this.level, holder);
+ // Paper end
if (ichunkaccess instanceof LevelChunk) {
((LevelChunk) ichunkaccess).setLoaded(false);
}
-@@ -575,7 +649,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -575,7 +649,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
this.lightEngine.tryScheduleUpdate();
this.progressListener.onStatusChange(ichunkaccess.getPos(), (ChunkStatus) null);
this.chunkSaveCooldowns.remove(ichunkaccess.getPos().toLong());
+- }
+ } else if (removed) { // Paper start
-+ for (int index = 0, len = this.regionManagers.size(); index < len; ++index) {
-+ this.regionManagers.get(index).removeChunk(holder.pos.x, holder.pos.z);
- }
-+ } // Paper end
++ net.minecraft.server.ChunkSystem.onChunkHolderDelete(this.level, holder);
++ } // Paper end
}
};
-@@ -1145,6 +1223,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -956,7 +1032,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+
+ this.viewDistance = j;
+ this.distanceManager.updatePlayerTickets(this.viewDistance + 1);
+- ObjectIterator objectiterator = this.updatingChunkMap.values().iterator();
++ Iterator objectiterator = net.minecraft.server.ChunkSystem.getUpdatingChunkHolders(this.level).iterator(); // Paper
+
+ while (objectiterator.hasNext()) {
+ ChunkHolder playerchunk = (ChunkHolder) objectiterator.next();
+@@ -999,7 +1075,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+ }
+
+ public int size() {
+- return this.visibleChunkMap.size();
++ return net.minecraft.server.ChunkSystem.getVisibleChunkHolderCount(this.level); // Paper
+ }
+
+ public DistanceManager getDistanceManager() {
+@@ -1007,19 +1083,19 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+ }
+
+ protected Iterable<ChunkHolder> getChunks() {
+- return Iterables.unmodifiableIterable(this.visibleChunkMap.values());
++ return Iterables.unmodifiableIterable(net.minecraft.server.ChunkSystem.getVisibleChunkHolders(this.level)); // Paper
+ }
+
+ void dumpChunks(Writer writer) throws IOException {
+ CsvOutput csvwriter = CsvOutput.builder().addColumn("x").addColumn("z").addColumn("level").addColumn("in_memory").addColumn("status").addColumn("full_status").addColumn("accessible_ready").addColumn("ticking_ready").addColumn("entity_ticking_ready").addColumn("ticket").addColumn("spawning").addColumn("block_entity_count").addColumn("ticking_ticket").addColumn("ticking_level").addColumn("block_ticks").addColumn("fluid_ticks").build(writer);
+ TickingTracker tickingtracker = this.distanceManager.tickingTracker();
+- ObjectBidirectionalIterator objectbidirectionaliterator = this.visibleChunkMap.long2ObjectEntrySet().iterator();
++ Iterator<ChunkHolder> objectbidirectionaliterator = net.minecraft.server.ChunkSystem.getVisibleChunkHolders(this.level).iterator(); // Paper
+
+ while (objectbidirectionaliterator.hasNext()) {
+- Entry<ChunkHolder> entry = (Entry) objectbidirectionaliterator.next();
+- long i = entry.getLongKey();
++ ChunkHolder playerchunk = objectbidirectionaliterator.next(); // Paper
++ long i = playerchunk.pos.toLong(); // Paper
+ ChunkPos chunkcoordintpair = new ChunkPos(i);
+- ChunkHolder playerchunk = (ChunkHolder) entry.getValue();
++ // Paper
+ Optional<ChunkAccess> optional = Optional.ofNullable(playerchunk.getLastAvailable());
+ Optional<LevelChunk> optional1 = optional.flatMap((ichunkaccess) -> {
+ return ichunkaccess instanceof LevelChunk ? Optional.of((LevelChunk) ichunkaccess) : Optional.empty();
+@@ -1145,6 +1221,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
if (!flag1) {
this.distanceManager.addPlayer(SectionPos.of((EntityAccess) player), player);
}
@@ -5475,7 +5855,7 @@ index 91a9b9ff0d7821a2261e7137fb1b3989ba096b88..6304a5b78ab1f3ef2478c7e2c493ebd7
} else {
SectionPos sectionposition = player.getLastSectionPos();
-@@ -1152,6 +1231,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -1152,6 +1229,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
if (!flag2) {
this.distanceManager.removePlayer(sectionposition, player);
}
@@ -5483,7 +5863,7 @@ index 91a9b9ff0d7821a2261e7137fb1b3989ba096b88..6304a5b78ab1f3ef2478c7e2c493ebd7
}
for (int k = i - this.viewDistance - 1; k <= i + this.viewDistance + 1; ++k) {
-@@ -1264,6 +1344,8 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -1264,6 +1342,8 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
}
}
@@ -5492,7 +5872,7 @@ index 91a9b9ff0d7821a2261e7137fb1b3989ba096b88..6304a5b78ab1f3ef2478c7e2c493ebd7
}
@Override
-@@ -1467,7 +1549,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -1467,7 +1547,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
public class ChunkDistanceManager extends DistanceManager {
protected ChunkDistanceManager(Executor workerExecutor, Executor mainThreadExecutor) {
@@ -5534,7 +5914,7 @@ index 6c98676827ceb6999f340fa2b06a0b3e1cb4cae2..f08089b8672454acf8c2309e850466b3
while (objectiterator.hasNext()) {
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
-index ce88976db29b9e9524dbe45b16721ef90afb692b..186a8f5895fedbaf27a7949d9bdbb1a9f2e36fbf 100644
+index ce88976db29b9e9524dbe45b16721ef90afb692b..96323a83d917516edf4b6951d1e881d2f5513bd0 100644
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
@@ -50,6 +50,7 @@ import net.minecraft.world.level.storage.LevelStorageSource;
@@ -5545,7 +5925,7 @@ index ce88976db29b9e9524dbe45b16721ef90afb692b..186a8f5895fedbaf27a7949d9bdbb1a9
public static final List<ChunkStatus> CHUNK_STATUSES = ChunkStatus.getStatusList();
private final DistanceManager distanceManager;
final ServerLevel level;
-@@ -68,6 +69,334 @@ public class ServerChunkCache extends ChunkSource {
+@@ -68,6 +69,151 @@ public class ServerChunkCache extends ChunkSource {
@Nullable
@VisibleForDebug
private NaturalSpawner.SpawnState lastSpawnState;
@@ -5597,7 +5977,7 @@ index ce88976db29b9e9524dbe45b16721ef90afb692b..186a8f5895fedbaf27a7949d9bdbb1a9
+
+ LevelChunk cachedChunk = this.lastLoadedChunks[cacheKey];
+ if (cachedChunk != null && cachedChunk.locX == x & cachedChunk.locZ == z) {
-+ return this.lastLoadedChunks[cacheKey];
++ return cachedChunk;
+ }
+
+ long chunkKey = ChunkPos.asLong(x, z);
@@ -5623,80 +6003,24 @@ index ce88976db29b9e9524dbe45b16721ef90afb692b..186a8f5895fedbaf27a7949d9bdbb1a9
+ long chunkFutureAwaitCounter; // Paper - private -> package private
+
+ public void getEntityTickingChunkAsync(int x, int z, java.util.function.Consumer<LevelChunk> onLoad) {
-+ if (Thread.currentThread() != this.mainThread) {
-+ this.mainThreadProcessor.execute(() -> {
-+ ServerChunkCache.this.getEntityTickingChunkAsync(x, z, onLoad);
-+ });
-+ return;
-+ }
-+ this.getChunkFutureAsynchronously(x, z, 31, ChunkHolder::getEntityTickingChunkFuture, onLoad);
++ net.minecraft.server.ChunkSystem.scheduleTickingState(
++ this.level, x, z, ChunkHolder.FullChunkStatus.ENTITY_TICKING, true,
++ ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority.NORMAL, onLoad
++ );
+ }
+
+ public void getTickingChunkAsync(int x, int z, java.util.function.Consumer<LevelChunk> onLoad) {
-+ if (Thread.currentThread() != this.mainThread) {
-+ this.mainThreadProcessor.execute(() -> {
-+ ServerChunkCache.this.getTickingChunkAsync(x, z, onLoad);
-+ });
-+ return;
-+ }
-+ this.getChunkFutureAsynchronously(x, z, 32, ChunkHolder::getTickingChunkFuture, onLoad);
++ net.minecraft.server.ChunkSystem.scheduleTickingState(
++ this.level, x, z, ChunkHolder.FullChunkStatus.TICKING, true,
++ ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority.NORMAL, onLoad
++ );
+ }
+
+ public void getFullChunkAsync(int x, int z, java.util.function.Consumer<LevelChunk> onLoad) {
-+ if (Thread.currentThread() != this.mainThread) {
-+ this.mainThreadProcessor.execute(() -> {
-+ ServerChunkCache.this.getFullChunkAsync(x, z, onLoad);
-+ });
-+ return;
-+ }
-+ this.getChunkFutureAsynchronously(x, z, 33, ChunkHolder::getFullChunkFuture, onLoad);
-+ }
-+
-+ private void getChunkFutureAsynchronously(int x, int z, int ticketLevel, java.util.function.Function<ChunkHolder, CompletableFuture<Either<LevelChunk, ChunkHolder.ChunkLoadingFailure>>> futureGet, java.util.function.Consumer<LevelChunk> onLoad) {
-+ if (Thread.currentThread() != this.mainThread) {
-+ throw new IllegalStateException();
-+ }
-+ ChunkPos chunkPos = new ChunkPos(x, z);
-+ Long identifier = this.chunkFutureAwaitCounter++;
-+ this.distanceManager.addTicket(TicketType.FUTURE_AWAIT, chunkPos, ticketLevel, identifier);
-+ this.runDistanceManagerUpdates();
-+
-+ ChunkHolder chunk = this.chunkMap.getUpdatingChunkIfPresent(chunkPos.toLong());
-+
-+ if (chunk == null) {
-+ throw new IllegalStateException("Expected playerchunk " + chunkPos + " in world '" + this.level.getWorld().getName() + "'");
-+ }
-+
-+ CompletableFuture<Either<LevelChunk, ChunkHolder.ChunkLoadingFailure>> future = futureGet.apply(chunk);
-+
-+ future.whenCompleteAsync((either, throwable) -> {
-+ try {
-+ if (throwable != null) {
-+ if (throwable instanceof ThreadDeath) {
-+ throw (ThreadDeath)throwable;
-+ }
-+ net.minecraft.server.MinecraftServer.LOGGER.error("Failed to complete future await for chunk " + chunkPos.toString() + " in world '" + ServerChunkCache.this.level.getWorld().getName() + "'", throwable);
-+ } else if (either.right().isPresent()) {
-+ net.minecraft.server.MinecraftServer.LOGGER.error("Failed to complete future await for chunk " + chunkPos.toString() + " in world '" + ServerChunkCache.this.level.getWorld().getName() + "': " + either.right().get().toString());
-+ }
-+
-+ try {
-+ if (onLoad != null) {
-+ onLoad.accept(either == null ? null : either.left().orElse(null)); // indicate failure to the callback.
-+ }
-+ } catch (Throwable thr) {
-+ if (thr instanceof ThreadDeath) {
-+ throw (ThreadDeath)thr;
-+ }
-+ net.minecraft.server.MinecraftServer.LOGGER.error("Load callback for future await failed " + chunkPos.toString() + " in world '" + ServerChunkCache.this.level.getWorld().getName() + "'", thr);
-+ return;
-+ }
-+ } finally {
-+ // due to odd behaviour with CB unload implementation we need to have these AFTER the load callback.
-+ ServerChunkCache.this.distanceManager.addTicket(TicketType.UNKNOWN, chunkPos, ticketLevel, chunkPos);
-+ ServerChunkCache.this.distanceManager.removeTicket(TicketType.FUTURE_AWAIT, chunkPos, ticketLevel, identifier);
-+ }
-+ }, this.mainThreadProcessor);
++ net.minecraft.server.ChunkSystem.scheduleTickingState(
++ this.level, x, z, ChunkHolder.FullChunkStatus.BORDER, true,
++ ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority.NORMAL, onLoad
++ );
+ }
+ // Paper end
+
@@ -5739,67 +6063,6 @@ index ce88976db29b9e9524dbe45b16721ef90afb692b..186a8f5895fedbaf27a7949d9bdbb1a9
+ }
+ }
+
-+ void getChunkAtAsynchronously(int chunkX, int chunkZ, int ticketLevel,
-+ java.util.function.Consumer<ChunkAccess> consumer) {
-+ this.getChunkAtAsynchronously(chunkX, chunkZ, ticketLevel, (ChunkHolder chunkHolder) -> {
-+ if (ticketLevel <= 33) {
-+ return (CompletableFuture)chunkHolder.getFullChunkFuture();
-+ } else {
-+ return chunkHolder.getOrScheduleFuture(ChunkHolder.getStatus(ticketLevel), ServerChunkCache.this.chunkMap);
-+ }
-+ }, consumer);
-+ }
-+
-+ void getChunkAtAsynchronously(int chunkX, int chunkZ, int ticketLevel,
-+ java.util.function.Function<ChunkHolder, CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>>> function,
-+ java.util.function.Consumer<ChunkAccess> consumer) {
-+ if (Thread.currentThread() != this.mainThread) {
-+ throw new IllegalStateException();
-+ }
-+
-+ ChunkPos chunkPos = new ChunkPos(chunkX, chunkZ);
-+ Long identifier = Long.valueOf(this.chunkFutureAwaitCounter++);
-+ this.addTicketAtLevel(TicketType.FUTURE_AWAIT, chunkPos, ticketLevel, identifier);
-+ this.runDistanceManagerUpdates();
-+
-+ ChunkHolder chunk = this.chunkMap.getUpdatingChunkIfPresent(chunkPos.toLong());
-+
-+ if (chunk == null) {
-+ throw new IllegalStateException("Expected playerchunk " + chunkPos + " in world '" + this.level.getWorld().getName() + "'");
-+ }
-+
-+ CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> future = function.apply(chunk);
-+
-+ future.whenCompleteAsync((either, throwable) -> {
-+ try {
-+ if (throwable != null) {
-+ if (throwable instanceof ThreadDeath) {
-+ throw (ThreadDeath)throwable;
-+ }
-+ LOGGER.error("Failed to complete future await for chunk " + chunkPos.toString() + " in world '" + ServerChunkCache.this.level.getWorld().getName() + "'", throwable);
-+ } else if (either.right().isPresent()) {
-+ LOGGER.error("Failed to complete future await for chunk " + chunkPos.toString() + " in world '" + ServerChunkCache.this.level.getWorld().getName() + "': " + either.right().get().toString());
-+ }
-+
-+ try {
-+ if (consumer != null) {
-+ consumer.accept(either == null ? null : either.left().orElse(null)); // indicate failure to the callback.
-+ }
-+ } catch (Throwable thr) {
-+ if (thr instanceof ThreadDeath) {
-+ throw (ThreadDeath)thr;
-+ }
-+ LOGGER.error("Load callback for future await failed " + chunkPos.toString() + " in world '" + ServerChunkCache.this.level.getWorld().getName() + "'", thr);
-+ return;
-+ }
-+ } finally {
-+ // due to odd behaviour with CB unload implementation we need to have these AFTER the load callback.
-+ ServerChunkCache.this.addTicketAtLevel(TicketType.UNKNOWN, chunkPos, ticketLevel, chunkPos);
-+ ServerChunkCache.this.removeTicketAtLevel(TicketType.FUTURE_AWAIT, chunkPos, ticketLevel, identifier);
-+ }
-+ }, this.mainThreadProcessor);
-+ }
-+
+ public <T> void addTicketAtLevel(TicketType<T> ticketType, ChunkPos chunkPos, int ticketLevel, T identifier) {
+ this.distanceManager.addTicket(ticketType, chunkPos, ticketLevel, identifier);
+ }
@@ -5808,79 +6071,13 @@ index ce88976db29b9e9524dbe45b16721ef90afb692b..186a8f5895fedbaf27a7949d9bdbb1a9
+ this.distanceManager.removeTicket(ticketType, chunkPos, ticketLevel, identifier);
+ }
+
-+ void chunkLoadAccept(int chunkX, int chunkZ, ChunkAccess chunk, java.util.function.Consumer<ChunkAccess> consumer) {
-+ try {
-+ consumer.accept(chunk);
-+ } catch (Throwable throwable) {
-+ if (throwable instanceof ThreadDeath) {
-+ throw (ThreadDeath)throwable;
-+ }
-+ LOGGER.error("Load callback for chunk " + chunkX + "," + chunkZ + " in world '" + this.level.getWorld().getName() + "' threw an exception", throwable);
-+ }
-+ }
-+
-+ public final void getChunkAtAsynchronously(int chunkX, int chunkZ, ChunkStatus status, boolean gen, boolean allowSubTicketLevel, java.util.function.Consumer<ChunkAccess> onLoad) {
-+ // try to fire sync
-+ int chunkStatusTicketLevel = 33 + ChunkStatus.getDistance(status);
-+ ChunkHolder playerChunk = this.chunkMap.getUpdatingChunkIfPresent(io.papermc.paper.util.CoordinateUtils.getChunkKey(chunkX, chunkZ));
-+ if (playerChunk != null) {
-+ ChunkStatus holderStatus = playerChunk.getChunkHolderStatus();
-+ ChunkAccess immediate = playerChunk.getAvailableChunkNow();
-+ if (immediate != null) {
-+ if (allowSubTicketLevel ? immediate.getStatus().isOrAfter(status) : (playerChunk.getTicketLevel() <= chunkStatusTicketLevel && holderStatus != null && holderStatus.isOrAfter(status))) {
-+ this.chunkLoadAccept(chunkX, chunkZ, immediate, onLoad);
-+ return;
-+ } else {
-+ if (gen || (!allowSubTicketLevel && immediate.getStatus().isOrAfter(status))) {
-+ this.getChunkAtAsynchronously(chunkX, chunkZ, chunkStatusTicketLevel, onLoad);
-+ return;
-+ } else {
-+ this.chunkLoadAccept(chunkX, chunkZ, null, onLoad);
-+ return;
-+ }
-+ }
-+ }
-+ }
-+
-+ // need to fire async
-+
-+ if (gen && !allowSubTicketLevel) {
-+ this.getChunkAtAsynchronously(chunkX, chunkZ, chunkStatusTicketLevel, onLoad);
-+ return;
-+ }
-+
-+ this.getChunkAtAsynchronously(chunkX, chunkZ, net.minecraft.server.MCUtil.getTicketLevelFor(ChunkStatus.EMPTY), (ChunkAccess chunk) -> {
-+ if (chunk == null) {
-+ throw new IllegalStateException("Chunk cannot be null");
-+ }
-+
-+ if (!chunk.getStatus().isOrAfter(status)) {
-+ if (gen) {
-+ this.getChunkAtAsynchronously(chunkX, chunkZ, chunkStatusTicketLevel, onLoad);
-+ return;
-+ } else {
-+ ServerChunkCache.this.chunkLoadAccept(chunkX, chunkZ, null, onLoad);
-+ return;
-+ }
-+ } else {
-+ if (allowSubTicketLevel) {
-+ ServerChunkCache.this.chunkLoadAccept(chunkX, chunkZ, chunk, onLoad);
-+ return;
-+ } else {
-+ this.getChunkAtAsynchronously(chunkX, chunkZ, chunkStatusTicketLevel, onLoad);
-+ return;
-+ }
-+ }
-+ });
-+ }
-+
-+ final io.papermc.paper.util.maplist.IteratorSafeOrderedReferenceSet<LevelChunk> tickingChunks = new io.papermc.paper.util.maplist.IteratorSafeOrderedReferenceSet<>(4096, 0.75f, 4096, 0.15, true);
-+ final io.papermc.paper.util.maplist.IteratorSafeOrderedReferenceSet<LevelChunk> entityTickingChunks = new io.papermc.paper.util.maplist.IteratorSafeOrderedReferenceSet<>(4096, 0.75f, 4096, 0.15, true);
++ public final io.papermc.paper.util.maplist.IteratorSafeOrderedReferenceSet<LevelChunk> tickingChunks = new io.papermc.paper.util.maplist.IteratorSafeOrderedReferenceSet<>(4096, 0.75f, 4096, 0.15, true);
++ public final io.papermc.paper.util.maplist.IteratorSafeOrderedReferenceSet<LevelChunk> entityTickingChunks = new io.papermc.paper.util.maplist.IteratorSafeOrderedReferenceSet<>(4096, 0.75f, 4096, 0.15, true);
+ // Paper end
public ServerChunkCache(ServerLevel world, LevelStorageSource.LevelStorageAccess session, DataFixer dataFixer, StructureTemplateManager structureTemplateManager, Executor workerExecutor, ChunkGenerator chunkGenerator, int viewDistance, int simulationDistance, boolean dsync, ChunkProgressListener worldGenerationProgressListener, ChunkStatusUpdateListener chunkStatusChangeListener, Supplier<DimensionDataStorage> persistentStateManagerFactory) {
this.level = world;
-@@ -120,6 +449,49 @@ public class ServerChunkCache extends ChunkSource {
+@@ -120,6 +266,49 @@ public class ServerChunkCache extends ChunkSource {
this.lastChunk[0] = chunk;
}
@@ -5930,7 +6127,7 @@ index ce88976db29b9e9524dbe45b16721ef90afb692b..186a8f5895fedbaf27a7949d9bdbb1a9
@Nullable
@Override
public ChunkAccess getChunk(int x, int z, ChunkStatus leastStatus, boolean create) {
-@@ -327,6 +699,12 @@ public class ServerChunkCache extends ChunkSource {
+@@ -327,6 +516,12 @@ public class ServerChunkCache extends ChunkSource {
}
}
@@ -5944,7 +6141,7 @@ index ce88976db29b9e9524dbe45b16721ef90afb692b..186a8f5895fedbaf27a7949d9bdbb1a9
ChunkHolder playerchunk = this.getVisibleChunkIfPresent(pos);
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index 4f1e8d36c363eb74e8f1e593f35a7bb8550f8918..95c3273d2379509cf6cd51a718f18b8697908932 100644
+index aa396df025115c7fd866cbc63a44c2c17abfde84..b2f79a0c9caa6783816afc36531c94378e832cb7 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -168,6 +168,7 @@ import org.bukkit.event.weather.LightningStrikeEvent;
@@ -5955,7 +6152,7 @@ index 4f1e8d36c363eb74e8f1e593f35a7bb8550f8918..95c3273d2379509cf6cd51a718f18b86
public class ServerLevel extends Level implements WorldGenLevel {
-@@ -223,6 +224,96 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -223,6 +224,98 @@ public class ServerLevel extends Level implements WorldGenLevel {
return convertable.dimensionType;
}
@@ -5989,11 +6186,11 @@ index 4f1e8d36c363eb74e8f1e593f35a7bb8550f8918..95c3273d2379509cf6cd51a718f18b86
+ return true;
+ }
+
-+ public final void loadChunksForMoveAsync(AABB axisalignedbb, double toX, double toZ,
++ public final void loadChunksForMoveAsync(AABB axisalignedbb, ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority priority,
+ java.util.function.Consumer<List<net.minecraft.world.level.chunk.ChunkAccess>> onLoad) {
+ if (Thread.currentThread() != this.thread) {
+ this.getChunkSource().mainThreadProcessor.execute(() -> {
-+ this.loadChunksForMoveAsync(axisalignedbb, toX, toZ, onLoad);
++ this.loadChunksForMoveAsync(axisalignedbb, priority, onLoad);
+ });
+ return;
+ }
@@ -6043,7 +6240,9 @@ index 4f1e8d36c363eb74e8f1e593f35a7bb8550f8918..95c3273d2379509cf6cd51a718f18b86
+
+ for (int cx = minChunkX; cx <= maxChunkX; ++cx) {
+ for (int cz = minChunkZ; cz <= maxChunkZ; ++cz) {
-+ chunkProvider.getChunkAtAsynchronously(cx, cz, net.minecraft.world.level.chunk.ChunkStatus.FULL, true, false, consumer);
++ net.minecraft.server.ChunkSystem.scheduleChunkLoad(
++ this, cx, cz, net.minecraft.world.level.chunk.ChunkStatus.FULL, true, priority, consumer
++ );
+ }
+ }
+ }
@@ -6053,7 +6252,7 @@ index 4f1e8d36c363eb74e8f1e593f35a7bb8550f8918..95c3273d2379509cf6cd51a718f18b86
public ServerLevel(MinecraftServer minecraftserver, Executor executor, LevelStorageSource.LevelStorageAccess convertable_conversionsession, PrimaryLevelData iworlddataserver, ResourceKey<Level> resourcekey, LevelStem worlddimension, ChunkProgressListener worldloadlistener, boolean flag, long i, List<CustomSpawner> list, boolean flag1, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider) {
// Holder holder = worlddimension.typeHolder(); // CraftBukkit - decompile error
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-index d9424f016060d7a2b446801c64c6cc0c3d826fb8..4759a0eceeccf28b62cb8865b423235d47d07443 100644
+index e2ed77972fcec43fef5f3af044479849f78901a9..84564ca128d2dfc79c0b5a13b699cf6fc80bdea7 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -243,6 +243,8 @@ public class ServerPlayer extends Player {
@@ -6790,6 +6989,128 @@ index 9668a960dbd3b4ff3c0635df2fb7cc1af289d235..603111a52346f678aba0fd66b010d8f3
@Override
public BlockState getBlockState(BlockPos pos) {
int i = pos.getY();
+diff --git a/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java b/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java
+index dfd1afc57664dd18c11f8a2547616074ccc55690..ab7eadf2fc4c4598fa89068332eaaf9a8e0a100f 100644
+--- a/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java
++++ b/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java
+@@ -90,6 +90,18 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
+ }
+
+ private boolean addEntity(T entity, boolean existing) {
++ // Paper start - chunk system hooks
++ if (existing) {
++ // I don't want to know why this is a generic type.
++ Entity entityCasted = (Entity)entity;
++ boolean wasRemoved = entityCasted.isRemoved();
++ net.minecraft.server.ChunkSystem.onEntityPreAdd((net.minecraft.server.level.ServerLevel)entityCasted.level, entityCasted);
++ if (!wasRemoved && entityCasted.isRemoved()) {
++ // removed by callback
++ return false;
++ }
++ }
++ // Paper end - chunk system hooks
+ if (!this.addEntityUuid(entity)) {
+ return false;
+ } else {
+diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+index 93308369f0bbd1e95569d9d573b8b6f42c8ae5a7..6d9469d577dcbb9d5b5b703cf47c8863e0b43b13 100644
+--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
++++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+@@ -234,8 +234,8 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+
+ @Override
+ public Chunk[] getLoadedChunks() {
+- Long2ObjectLinkedOpenHashMap<ChunkHolder> chunks = this.world.getChunkSource().chunkMap.visibleChunkMap;
+- return chunks.values().stream().map(ChunkHolder::getFullChunkNow).filter(Objects::nonNull).map(net.minecraft.world.level.chunk.LevelChunk::getBukkitChunk).toArray(Chunk[]::new);
++ List<ChunkHolder> chunks = net.minecraft.server.ChunkSystem.getVisibleChunkHolders(this.world); // Paper
++ return chunks.stream().map(ChunkHolder::getFullChunkNow).filter(Objects::nonNull).map(net.minecraft.world.level.chunk.LevelChunk::getBukkitChunk).toArray(Chunk[]::new);
+ }
+
+ @Override
+@@ -310,7 +310,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+
+ @Override
+ public boolean refreshChunk(int x, int z) {
+- ChunkHolder playerChunk = this.world.getChunkSource().chunkMap.visibleChunkMap.get(ChunkPos.asLong(x, z));
++ ChunkHolder playerChunk = this.world.getChunkSource().chunkMap.getVisibleChunkIfPresent(ChunkPos.asLong(x, z));
+ if (playerChunk == null) return false;
+
+ playerChunk.getTickingChunkFuture().thenAccept(either -> {
+@@ -1943,4 +1943,32 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+ return this.spigot;
+ }
+ // Spigot end
++ // Paper start
++ public java.util.concurrent.CompletableFuture<Chunk> getChunkAtAsync(int x, int z, boolean gen, boolean urgent) {
++ if (Bukkit.isPrimaryThread()) {
++ net.minecraft.world.level.chunk.LevelChunk immediate = this.world.getChunkSource().getChunkAtIfLoadedImmediately(x, z);
++ if (immediate != null) {
++ return java.util.concurrent.CompletableFuture.completedFuture(immediate.getBukkitChunk());
++ }
++ }
++
++ ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority priority;
++ if (urgent) {
++ priority = ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority.HIGHER;
++ } else {
++ priority = ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority.NORMAL;
++ }
++
++ java.util.concurrent.CompletableFuture<Chunk> ret = new java.util.concurrent.CompletableFuture<>();
++
++ net.minecraft.server.ChunkSystem.scheduleChunkLoad(this.getHandle(), x, z, gen, ChunkStatus.FULL, true, priority, (c) -> {
++ net.minecraft.server.MinecraftServer.getServer().scheduleOnMain(() -> {
++ net.minecraft.world.level.chunk.LevelChunk chunk = (net.minecraft.world.level.chunk.LevelChunk)c;
++ ret.complete(chunk == null ? null : chunk.getBukkitChunk());
++ });
++ });
++
++ return ret;
++ }
++ // Paper end
+ }
+diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+index ef27c0f94355ec7be4a314a0f93bc1c146012210..71c1595b59b757441304a158367d750ed509e4d1 100644
+--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+@@ -1128,4 +1128,37 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
+ return this.spigot;
+ }
+ // Spigot end
++
++ // Paper start
++ @Override
++ public java.util.concurrent.CompletableFuture<Boolean> teleportAsync(Location location, TeleportCause cause) {
++ Preconditions.checkArgument(location != null, "location");
++ location.checkFinite();
++ Location locationClone = location.clone(); // clone so we don't need to worry about mutations after this call.
++
++ net.minecraft.server.level.ServerLevel world = ((CraftWorld)locationClone.getWorld()).getHandle();
++ java.util.concurrent.CompletableFuture<Boolean> ret = new java.util.concurrent.CompletableFuture<>();
++
++ world.loadChunksForMoveAsync(getHandle().getBoundingBoxAt(locationClone.getX(), locationClone.getY(), locationClone.getZ()),
++ this instanceof CraftPlayer ? ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority.HIGHER : ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority.NORMAL, (list) -> {
++ net.minecraft.server.level.ServerChunkCache chunkProviderServer = world.getChunkSource();
++ for (net.minecraft.world.level.chunk.ChunkAccess chunk : list) {
++ chunkProviderServer.addTicketAtLevel(net.minecraft.server.level.TicketType.POST_TELEPORT, chunk.getPos(), 33, CraftEntity.this.getEntityId());
++ }
++ net.minecraft.server.MinecraftServer.getServer().scheduleOnMain(() -> {
++ try {
++ ret.complete(CraftEntity.this.teleport(locationClone, cause) ? Boolean.TRUE : Boolean.FALSE);
++ } catch (Throwable throwable) {
++ if (throwable instanceof ThreadDeath) {
++ throw (ThreadDeath)throwable;
++ }
++ net.minecraft.server.MinecraftServer.LOGGER.error("Failed to teleport entity " + CraftEntity.this, throwable);
++ ret.completeExceptionally(throwable);
++ }
++ });
++ });
++
++ return ret;
++ }
++ // Paper end
+ }
diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
index 2f52148f36e56c503e619634eedd3d46d9f44938..054fcc3713f02e358dfe049491c8d1689ccc750b 100644
--- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
@@ -7013,7 +7334,7 @@ index 0000000000000000000000000000000000000000..909b2c98e7a9117d2f737245e4661792
+ }
+}
diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
-index 96bbfe115f4fcd9b5bfe733ee8e0a64f5dcf4198..8c5165c449f740e51aad3f41405aaad1cfe5c657 100644
+index 3568b1a579716bee7f749eb944784b59b361f6df..d805ac4274fb6149bf8efea6b771ecfe79aea76f 100644
--- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
@@ -100,8 +100,17 @@ public final class CraftMagicNumbers implements UnsafeValues {
diff --git a/patches/server/0008-Adventure.patch b/patches/server/0009-Adventure.patch
index 92350d9dc2..4e3bfbad3a 100644
--- a/patches/server/0008-Adventure.patch
+++ b/patches/server/0009-Adventure.patch
@@ -2691,7 +2691,7 @@ index 4dd952faac05f553b28d1252296b0587369865f4..6139a06453e370865889f47644a6840f
+ // Paper end
}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-index 93308369f0bbd1e95569d9d573b8b6f42c8ae5a7..cf7762e76a2d35acdfc12627e9750fbec766d555 100644
+index 6d9469d577dcbb9d5b5b703cf47c8863e0b43b13..9a6820b10e4164cc38d269853b5c2a49175cb890 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -150,6 +150,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@@ -2702,10 +2702,10 @@ index 93308369f0bbd1e95569d9d573b8b6f42c8ae5a7..cf7762e76a2d35acdfc12627e9750fbe
private static final Random rand = new Random();
-@@ -1943,4 +1944,18 @@ public class CraftWorld extends CraftRegionAccessor implements World {
- return this.spigot;
+@@ -1970,5 +1971,18 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+
+ return ret;
}
- // Spigot end
+
+ // Paper start - implement pointers
+ @Override
@@ -2719,7 +2719,7 @@ index 93308369f0bbd1e95569d9d573b8b6f42c8ae5a7..cf7762e76a2d35acdfc12627e9750fbe
+
+ return this.adventure$pointers;
+ }
-+ // Paper end
+ // Paper end
}
diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java
index e8d71985f2e96574081e4f609d62a3b8bded8249..681b58e6de48cccac82c7b6833f6fcea46d83dde 100644
@@ -3089,7 +3089,7 @@ index 53b5af4179cc4bc4d5646f183da5e327a45237ac..a859a675b4bc543e139358223cc92ad5
public net.minecraft.world.item.enchantment.Enchantment getHandle() {
return this.target;
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
-index ef27c0f94355ec7be4a314a0f93bc1c146012210..64687b0e04f619576f3e7f4fec0b559408048d38 100644
+index 71c1595b59b757441304a158367d750ed509e4d1..7c9dcf62f85bb3ddffb4eadb3961d7b356c503f8 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
@@ -196,6 +196,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
diff --git a/patches/server/0009-Paper-command.patch b/patches/server/0010-Paper-command.patch
index 7a3a1c2956..a1cbd38e7e 100644
--- a/patches/server/0009-Paper-command.patch
+++ b/patches/server/0010-Paper-command.patch
@@ -559,7 +559,7 @@ index 08ae7a96e93c0d8547f560b3f753804525621c6b..8f29bb843fc456384f7b4e216afca501
this.setPvpAllowed(dedicatedserverproperties.pvp);
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-index e4f8ccb45a16c35b5256e209435840609d527695..82199864f2046528358af08d4aa4a283fa3e7ffd 100644
+index 6139a06453e370865889f47644a6840fce2934f2..295318717fc603b3adc58fbda39bd65e97462b88 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -896,6 +896,7 @@ public final class CraftServer implements Server {
diff --git a/patches/server/0012-Timings-v2.patch b/patches/server/0012-Timings-v2.patch
index df9edbac22..71da852f12 100644
--- a/patches/server/0012-Timings-v2.patch
+++ b/patches/server/0012-Timings-v2.patch
@@ -997,7 +997,7 @@ index f4a6a6addbba65b3415320977048aeba0eadba63..c905602d23cdf3af1de7ab4419f11856
}
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
-index 6304a5b78ab1f3ef2478c7e2c493ebd760b5508e..ca1e483819bffc948fab10f88563084aa75d1484 100644
+index 1fbe1b6de925f71763f79fe3d2371b70a8650f25..2a9e5fb8164f79b0f9c1cb5497216e51f9df3454 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -1,8 +1,10 @@
@@ -1011,7 +1011,7 @@ index 6304a5b78ab1f3ef2478c7e2c493ebd760b5508e..ca1e483819bffc948fab10f88563084a
import com.google.common.collect.Lists;
import com.google.common.collect.Queues;
import com.google.common.collect.Sets;
-@@ -854,6 +856,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -852,6 +854,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
ChunkStatus chunkstatus = ChunkHolder.getStatus(chunkHolder.getTicketLevel());
return !chunkstatus.isOrAfter(ChunkStatus.FULL) ? ChunkHolder.UNLOADED_CHUNK : either.mapLeft((ichunkaccess) -> {
@@ -1019,7 +1019,7 @@ index 6304a5b78ab1f3ef2478c7e2c493ebd760b5508e..ca1e483819bffc948fab10f88563084a
ChunkPos chunkcoordintpair = chunkHolder.getPos();
ProtoChunk protochunk = (ProtoChunk) ichunkaccess;
LevelChunk chunk;
-@@ -878,6 +881,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -876,6 +879,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
}
return chunk;
@@ -1027,7 +1027,7 @@ index 6304a5b78ab1f3ef2478c7e2c493ebd760b5508e..ca1e483819bffc948fab10f88563084a
});
}, (runnable) -> {
ProcessorHandle mailbox = this.mainThreadMailbox;
-@@ -1430,6 +1434,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -1428,6 +1432,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
List<ServerPlayer> list = Lists.newArrayList();
List<ServerPlayer> list1 = this.level.players();
ObjectIterator objectiterator = this.entityMap.values().iterator();
@@ -1035,7 +1035,7 @@ index 6304a5b78ab1f3ef2478c7e2c493ebd760b5508e..ca1e483819bffc948fab10f88563084a
ChunkMap.TrackedEntity playerchunkmap_entitytracker;
-@@ -1454,14 +1459,17 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -1452,14 +1457,17 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
playerchunkmap_entitytracker.serverEntity.sendChanges();
}
}
@@ -1054,10 +1054,10 @@ index 6304a5b78ab1f3ef2478c7e2c493ebd760b5508e..ca1e483819bffc948fab10f88563084a
}
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
-index 186a8f5895fedbaf27a7949d9bdbb1a9f2e36fbf..86acdd910eebb8beac4536942119c9e97580ff2e 100644
+index 96323a83d917516edf4b6951d1e881d2f5513bd0..514111ed7fe8aec0d5f15f7a8f157d5872a56e4f 100644
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
-@@ -517,13 +517,15 @@ public class ServerChunkCache extends ChunkSource {
+@@ -334,13 +334,15 @@ public class ServerChunkCache extends ChunkSource {
}
gameprofilerfiller.incrementCounter("getChunkCacheMiss");
@@ -1075,7 +1075,7 @@ index 186a8f5895fedbaf27a7949d9bdbb1a9f2e36fbf..86acdd910eebb8beac4536942119c9e9
ichunkaccess = (ChunkAccess) ((Either) completablefuture.join()).map((ichunkaccess1) -> {
return ichunkaccess1;
}, (playerchunk_failure) -> {
-@@ -721,7 +723,9 @@ public class ServerChunkCache extends ChunkSource {
+@@ -538,7 +540,9 @@ public class ServerChunkCache extends ChunkSource {
public void save(boolean flush) {
this.runDistanceManagerUpdates();
@@ -1085,7 +1085,7 @@ index 186a8f5895fedbaf27a7949d9bdbb1a9f2e36fbf..86acdd910eebb8beac4536942119c9e9
}
@Override
-@@ -760,7 +764,9 @@ public class ServerChunkCache extends ChunkSource {
+@@ -577,7 +581,9 @@ public class ServerChunkCache extends ChunkSource {
this.level.timings.doChunkMap.stopTiming(); // Spigot
this.level.getProfiler().popPush("chunks");
if (tickChunks) {
@@ -1095,7 +1095,7 @@ index 186a8f5895fedbaf27a7949d9bdbb1a9f2e36fbf..86acdd910eebb8beac4536942119c9e9
}
this.level.timings.doChunkUnload.startTiming(); // Spigot
-@@ -789,13 +795,16 @@ public class ServerChunkCache extends ChunkSource {
+@@ -606,13 +612,16 @@ public class ServerChunkCache extends ChunkSource {
boolean flag1 = level.ticksPerSpawnCategory.getLong(org.bukkit.entity.SpawnCategory.ANIMAL) != 0L && worlddata.getGameTime() % level.ticksPerSpawnCategory.getLong(org.bukkit.entity.SpawnCategory.ANIMAL) == 0L; // CraftBukkit
gameprofilerfiller.push("naturalSpawnCount");
@@ -1112,7 +1112,7 @@ index 186a8f5895fedbaf27a7949d9bdbb1a9f2e36fbf..86acdd910eebb8beac4536942119c9e9
while (iterator.hasNext()) {
ChunkHolder playerchunk = (ChunkHolder) iterator.next();
-@@ -824,27 +833,27 @@ public class ServerChunkCache extends ChunkSource {
+@@ -641,27 +650,27 @@ public class ServerChunkCache extends ChunkSource {
}
if (this.level.shouldTickBlocksAt(chunkcoordintpair.toLong())) {
@@ -1146,7 +1146,7 @@ index 186a8f5895fedbaf27a7949d9bdbb1a9f2e36fbf..86acdd910eebb8beac4536942119c9e9
}
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index a60af68365b4cb0e09061e1956d2ae6790659bc0..28669f2e9c4a49322fe44c730b2ed145c9c61273 100644
+index b2f79a0c9caa6783816afc36531c94378e832cb7..99d44faab5b5da244fdc170c73d73723c174c8fd 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -1,6 +1,8 @@
@@ -1166,7 +1166,7 @@ index a60af68365b4cb0e09061e1956d2ae6790659bc0..28669f2e9c4a49322fe44c730b2ed145
import org.bukkit.craftbukkit.event.CraftEventFactory;
import org.bukkit.craftbukkit.generator.CustomWorldChunkManager;
import org.bukkit.craftbukkit.util.CraftNamespacedKey;
-@@ -447,7 +448,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -449,7 +450,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
this.updateSkyBrightness();
this.tickTime();
gameprofilerfiller.popPush("tickPending");
@@ -1175,7 +1175,7 @@ index a60af68365b4cb0e09061e1956d2ae6790659bc0..28669f2e9c4a49322fe44c730b2ed145
if (!this.isDebug()) {
j = this.getGameTime();
gameprofilerfiller.push("blockTicks");
-@@ -456,12 +457,16 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -458,12 +459,16 @@ public class ServerLevel extends Level implements WorldGenLevel {
this.fluidTicks.tick(j, 65536, this::tickFluid);
gameprofilerfiller.pop();
}
@@ -1193,7 +1193,7 @@ index a60af68365b4cb0e09061e1956d2ae6790659bc0..28669f2e9c4a49322fe44c730b2ed145
gameprofilerfiller.popPush("blockEvents");
timings.doSounds.startTiming(); // Spigot
this.runBlockEvents();
-@@ -628,6 +633,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -630,6 +635,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
}
gameprofilerfiller.popPush("tickBlocks");
@@ -1201,7 +1201,7 @@ index a60af68365b4cb0e09061e1956d2ae6790659bc0..28669f2e9c4a49322fe44c730b2ed145
if (randomTickSpeed > 0) {
LevelChunkSection[] achunksection = chunk.getSections();
int l = achunksection.length;
-@@ -660,6 +666,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -662,6 +668,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
}
}
@@ -1209,7 +1209,7 @@ index a60af68365b4cb0e09061e1956d2ae6790659bc0..28669f2e9c4a49322fe44c730b2ed145
gameprofilerfiller.pop();
}
-@@ -894,14 +901,22 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -896,14 +903,22 @@ public class ServerLevel extends Level implements WorldGenLevel {
}
public void tickNonPassenger(Entity entity) {
@@ -1233,7 +1233,7 @@ index a60af68365b4cb0e09061e1956d2ae6790659bc0..28669f2e9c4a49322fe44c730b2ed145
entity.setOldPosAndRot();
ProfilerFiller gameprofilerfiller = this.getProfiler();
-@@ -920,7 +935,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -922,7 +937,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
this.tickPassenger(entity, entity1);
}
@@ -1242,7 +1242,7 @@ index a60af68365b4cb0e09061e1956d2ae6790659bc0..28669f2e9c4a49322fe44c730b2ed145
}
-@@ -962,6 +977,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -964,6 +979,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
if (!savingDisabled) {
org.bukkit.Bukkit.getPluginManager().callEvent(new org.bukkit.event.world.WorldSaveEvent(getWorld())); // CraftBukkit
@@ -1250,7 +1250,7 @@ index a60af68365b4cb0e09061e1956d2ae6790659bc0..28669f2e9c4a49322fe44c730b2ed145
if (progressListener != null) {
progressListener.progressStartNoAbort(Component.translatable("menu.savingLevel"));
}
-@@ -971,7 +987,10 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -973,7 +989,10 @@ public class ServerLevel extends Level implements WorldGenLevel {
progressListener.progressStage(Component.translatable("menu.savingChunks"));
}
diff --git a/patches/server/0010-Not-implemeneted.patch b/patches/server/0013-Not-implemeneted.patch
index 55e55d31d4..3f8aab22dd 100644
--- a/patches/server/0010-Not-implemeneted.patch
+++ b/patches/server/0013-Not-implemeneted.patch
@@ -7,13 +7,14 @@ Currently a placeholder patch.
diff --git a/src/main/java/io/papermc/paper/util/TickThread.java b/src/main/java/io/papermc/paper/util/TickThread.java
new file mode 100644
-index 0000000000000000000000000000000000000000..be130b03ca116fd6d104df26c32312db1655b09e
+index 0000000000000000000000000000000000000000..d59885ee9c8b29d5bac34dce0597e345e5358c77
--- /dev/null
+++ b/src/main/java/io/papermc/paper/util/TickThread.java
-@@ -0,0 +1,78 @@
+@@ -0,0 +1,79 @@
+package io.papermc.paper.util;
+
+import net.minecraft.server.MinecraftServer;
++import net.minecraft.server.level.ServerLevel;
+import net.minecraft.world.entity.Entity;
+import org.bukkit.Bukkit;
+import java.util.concurrent.atomic.AtomicInteger;
@@ -42,15 +43,15 @@ index 0000000000000000000000000000000000000000..be130b03ca116fd6d104df26c32312db
+ }
+ }
+
-+ public static void ensureTickThread(final int chunkX, final int chunkZ, final String reason) {
-+ if (!isTickThreadFor(chunkX, chunkZ)) {
++ public static void ensureTickThread(final ServerLevel world, final int chunkX, final int chunkZ, final String reason) {
++ if (!isTickThreadFor(world, chunkX, chunkZ)) {
+ MinecraftServer.LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable());
+ throw new IllegalStateException(reason);
+ }
+ }
+
+ public static void ensureTickThread(final Entity entity, final String reason) {
-+ if (!isTickThreadFor(entity.chunkPosition().x, entity.chunkPosition().z)) {
++ if (!isTickThreadFor(entity)) {
+ MinecraftServer.LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable());
+ throw new IllegalStateException(reason);
+ }
@@ -81,7 +82,7 @@ index 0000000000000000000000000000000000000000..be130b03ca116fd6d104df26c32312db
+ return Bukkit.isPrimaryThread();
+ }
+
-+ public static boolean isTickThreadFor(final int chunkX, final int chunkZ) {
++ public static boolean isTickThreadFor(final ServerLevel world, final int chunkX, final int chunkZ) {
+ return Bukkit.isPrimaryThread();
+ }
+
diff --git a/patches/server/0320-ChunkMapDistance-CME.patch b/patches/server/0014-ChunkMapDistance-CME.patch
index 74fcd81751..956878857c 100644
--- a/patches/server/0320-ChunkMapDistance-CME.patch
+++ b/patches/server/0014-ChunkMapDistance-CME.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] ChunkMapDistance CME
diff --git a/src/main/java/net/minecraft/server/level/ChunkHolder.java b/src/main/java/net/minecraft/server/level/ChunkHolder.java
-index 90fcb4dc89643b1c706ea4554595a842198558a1..6e7d09cd48048957a14835b857ac708aafe8f664 100644
+index 0873134f1f6de0c372ba28b89a20302c9a0115d8..e30893d6cbe3b42338d04453d0f452babeb61d8a 100644
--- a/src/main/java/net/minecraft/server/level/ChunkHolder.java
+++ b/src/main/java/net/minecraft/server/level/ChunkHolder.java
@@ -73,6 +73,7 @@ public class ChunkHolder {
@@ -15,9 +15,9 @@ index 90fcb4dc89643b1c706ea4554595a842198558a1..6e7d09cd48048957a14835b857ac708a
+ boolean isUpdateQueued = false; // Paper
private final ChunkMap chunkMap; // Paper
- public ChunkHolder(ChunkPos pos, int level, LevelHeightAccessor world, LevelLightEngine lightingProvider, ChunkHolder.LevelChangeListener levelUpdateListener, ChunkHolder.PlayerProvider playersWatchingChunkProvider) {
+ // Paper start
diff --git a/src/main/java/net/minecraft/server/level/DistanceManager.java b/src/main/java/net/minecraft/server/level/DistanceManager.java
-index ab785bfc29c0b120b7c6fed2d15460c86e020291..1e066a35b53b1f71a0e6376a22d51fc4c0a412dc 100644
+index f08089b8672454acf8c2309e850466b335248692..6181f675d7addde30f7018b4cd46fe061a14da51 100644
--- a/src/main/java/net/minecraft/server/level/DistanceManager.java
+++ b/src/main/java/net/minecraft/server/level/DistanceManager.java
@@ -52,7 +52,16 @@ public abstract class DistanceManager {
diff --git a/patches/server/0015-Do-not-copy-visible-chunks.patch b/patches/server/0015-Do-not-copy-visible-chunks.patch
new file mode 100644
index 0000000000..0f5350c531
--- /dev/null
+++ b/patches/server/0015-Do-not-copy-visible-chunks.patch
@@ -0,0 +1,122 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Spottedleaf <[email protected]>
+Date: Sun, 21 Mar 2021 11:22:10 -0700
+Subject: [PATCH] Do not copy visible chunks
+
+For servers with a lot of chunk holders, copying for each
+tickDistanceManager call can take up quite a bit in
+the function. I saw approximately 1/3rd of the function
+on the copy.
+
+diff --git a/src/main/java/net/minecraft/server/ChunkSystem.java b/src/main/java/net/minecraft/server/ChunkSystem.java
+index 83dc09f6526206690c474b50a7a6e71cefc93ab4..7f76c304f5eb3c2f27b348918588ab67b795b1ba 100644
+--- a/src/main/java/net/minecraft/server/ChunkSystem.java
++++ b/src/main/java/net/minecraft/server/ChunkSystem.java
+@@ -202,19 +202,24 @@ public final class ChunkSystem {
+ }
+
+ public static List<ChunkHolder> getVisibleChunkHolders(final ServerLevel level) {
+- return new ArrayList<>(level.chunkSource.chunkMap.visibleChunkMap.values());
++ if (Bukkit.isPrimaryThread()) {
++ return level.chunkSource.chunkMap.updatingChunks.getVisibleValuesCopy();
++ }
++ synchronized (level.chunkSource.chunkMap.updatingChunks) {
++ return level.chunkSource.chunkMap.updatingChunks.getVisibleValuesCopy();
++ }
+ }
+
+ public static List<ChunkHolder> getUpdatingChunkHolders(final ServerLevel level) {
+- return new ArrayList<>(level.chunkSource.chunkMap.updatingChunkMap.values());
++ return level.chunkSource.chunkMap.updatingChunks.getUpdatingValuesCopy();
+ }
+
+ public static int getVisibleChunkHolderCount(final ServerLevel level) {
+- return level.chunkSource.chunkMap.visibleChunkMap.size();
++ return level.chunkSource.chunkMap.updatingChunks.getVisibleMap().size();
+ }
+
+ public static int getUpdatingChunkHolderCount(final ServerLevel level) {
+- return level.chunkSource.chunkMap.updatingChunkMap.size();
++ return level.chunkSource.chunkMap.updatingChunks.getUpdatingMap().size();
+ }
+
+ public static boolean hasAnyChunkHolders(final ServerLevel level) {
+diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
+index 2a9e5fb8164f79b0f9c1cb5497216e51f9df3454..ea27e6b1340a42c675bc68ed75f100569114be7a 100644
+--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
++++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
+@@ -121,9 +121,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+ private static final int MIN_VIEW_DISTANCE = 3;
+ public static final int MAX_VIEW_DISTANCE = 33;
+ public static final int MAX_CHUNK_DISTANCE = 33 + ChunkStatus.maxDistance();
++ // Paper start - Don't copy
++ public final com.destroystokyo.paper.util.map.QueuedChangesMapLong2Object<ChunkHolder> updatingChunks = new com.destroystokyo.paper.util.map.QueuedChangesMapLong2Object<>();
++ // Paper end - Don't copy
+ public static final int FORCED_TICKET_LEVEL = 31;
+- public final Long2ObjectLinkedOpenHashMap<ChunkHolder> updatingChunkMap = new Long2ObjectLinkedOpenHashMap();
+- public volatile Long2ObjectLinkedOpenHashMap<ChunkHolder> visibleChunkMap;
++ // Paper - Don't copy
+ private final Long2ObjectLinkedOpenHashMap<ChunkHolder> pendingUnloads;
+ public final LongSet entitiesInLevel;
+ public final ServerLevel level;
+@@ -224,7 +226,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+
+ public ChunkMap(ServerLevel world, LevelStorageSource.LevelStorageAccess session, DataFixer dataFixer, StructureTemplateManager structureTemplateManager, Executor executor, BlockableEventLoop<Runnable> mainThreadExecutor, LightChunkGetter chunkProvider, ChunkGenerator chunkGenerator, ChunkProgressListener worldGenerationProgressListener, ChunkStatusUpdateListener chunkStatusChangeListener, Supplier<DimensionDataStorage> persistentStateManagerFactory, int viewDistance, boolean dsync) {
+ super(session.getDimensionPath(world.dimension()).resolve("region"), dataFixer, dsync);
+- this.visibleChunkMap = this.updatingChunkMap.clone();
++ // Paper - don't copy
+ this.pendingUnloads = new Long2ObjectLinkedOpenHashMap();
+ this.entitiesInLevel = new LongOpenHashSet();
+ this.toDrop = new LongOpenHashSet();
+@@ -327,12 +329,17 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+
+ @Nullable
+ public ChunkHolder getUpdatingChunkIfPresent(long pos) {
+- return (ChunkHolder) this.updatingChunkMap.get(pos);
++ return this.updatingChunks.getUpdating(pos); // Paper - Don't copy
+ }
+
+ @Nullable
+ public ChunkHolder getVisibleChunkIfPresent(long pos) {
+- return (ChunkHolder) this.visibleChunkMap.get(pos);
++ // Paper start - Don't copy
++ if (Thread.currentThread() == this.level.thread) {
++ return this.updatingChunks.getVisible(pos);
++ }
++ return this.updatingChunks.getVisibleAsync(pos);
++ // Paper end - Don't copy
+ }
+
+ protected IntSupplier getChunkQueueLevel(long pos) {
+@@ -515,7 +522,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+ // Paper start
+ holder.onChunkAdd();
+ // Paper end
+- this.updatingChunkMap.put(pos, holder);
++ this.updatingChunks.queueUpdate(pos, holder); // Paper - Don't copy
+ this.modified = true;
+ }
+
+@@ -592,7 +599,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+
+ for (int i = 0; longiterator.hasNext() && (shouldKeepTicking.getAsBoolean() || i < 200 || this.toDrop.size() > 2000); longiterator.remove()) {
+ long j = longiterator.nextLong();
+- ChunkHolder playerchunk = (ChunkHolder) this.updatingChunkMap.remove(j);
++ ChunkHolder playerchunk = this.updatingChunks.queueRemove(j); // Paper - Don't copy
+
+ if (playerchunk != null) {
+ playerchunk.onChunkRemove(); // Paper
+@@ -672,7 +679,12 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+ if (!this.modified) {
+ return false;
+ } else {
+- this.visibleChunkMap = this.updatingChunkMap.clone();
++ // Paper start - Don't copy
++ synchronized (this.updatingChunks) {
++ this.updatingChunks.performUpdates();
++ }
++ // Paper end - Don't copy
++
+ this.modified = false;
+ return true;
+ }
diff --git a/patches/server/0321-Chunk-debug-command.patch b/patches/server/0016-Chunk-debug-command.patch
index 79c5f0f128..79581b2b72 100644
--- a/patches/server/0321-Chunk-debug-command.patch
+++ b/patches/server/0016-Chunk-debug-command.patch
@@ -32,7 +32,7 @@ https://bugs.mojang.com/browse/MC-141484?focusedCommentId=528273&page=com.atlass
https://bugs.mojang.com/browse/MC-141484?focusedCommentId=528577&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-528577
diff --git a/src/main/java/io/papermc/paper/command/PaperCommand.java b/src/main/java/io/papermc/paper/command/PaperCommand.java
-index cd4936ef114b504df8649fba8f1823d94a4bb2a2..395c43f6440c1e0e47919eef096ea8a8d552ccec 100644
+index b3a58bf4b654e336826dc04da9e2f80ff8b9a9a7..8e773f522521d2dd6349c87b582a3337b76f161f 100644
--- a/src/main/java/io/papermc/paper/command/PaperCommand.java
+++ b/src/main/java/io/papermc/paper/command/PaperCommand.java
@@ -1,5 +1,6 @@
@@ -52,7 +52,7 @@ index cd4936ef114b504df8649fba8f1823d94a4bb2a2..395c43f6440c1e0e47919eef096ea8a8
.flatMap(entry -> entry.getKey().stream().map(s -> Map.entry(s, entry.getValue())))
diff --git a/src/main/java/io/papermc/paper/command/subcommands/ChunkDebugCommand.java b/src/main/java/io/papermc/paper/command/subcommands/ChunkDebugCommand.java
new file mode 100644
-index 0000000000000000000000000000000000000000..029ad37df71e74d9feb57e4b31b3602e55d49113
+index 0000000000000000000000000000000000000000..28a9550449be9a212f054b02e43fbd8a3781efcf
--- /dev/null
+++ b/src/main/java/io/papermc/paper/command/subcommands/ChunkDebugCommand.java
@@ -0,0 +1,166 @@
@@ -148,14 +148,14 @@ index 0000000000000000000000000000000000000000..029ad37df71e74d9feb57e4b31b3602e
+ int ticking = 0;
+ int entityTicking = 0;
+
-+ for (final ChunkHolder chunk : world.getChunkSource().chunkMap.updatingChunkMap.values()) {
++ for (final ChunkHolder chunk : net.minecraft.server.ChunkSystem.getVisibleChunkHolders(world)) {
+ if (chunk.getFullChunkNowUnchecked() == null) {
+ continue;
+ }
+
+ ++total;
+
-+ ChunkHolder.FullChunkStatus state = ChunkHolder.getFullChunkStatus(chunk.getTicketLevel());
++ ChunkHolder.FullChunkStatus state = chunk.getFullStatus();
+
+ switch (state) {
+ case INACCESSIBLE -> ++inactive;
@@ -223,17 +223,25 @@ index 0000000000000000000000000000000000000000..029ad37df71e74d9feb57e4b31b3602e
+
+}
diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java
-index 162aa7718488a74980843944e0d026ccfd5a65a5..4e29c0a983727fc839a4bcde01d3286396b3587d 100644
+index b310d51b7fe3e8cef0a450674725969fe1ce78a4..2e56c52e3ee45b0304a9e6a5eab863ef96b2aab0 100644
--- a/src/main/java/net/minecraft/server/MCUtil.java
+++ b/src/main/java/net/minecraft/server/MCUtil.java
-@@ -9,13 +9,27 @@ import net.minecraft.core.BlockPos;
+@@ -1,15 +1,27 @@
+ package net.minecraft.server;
+
+ import com.google.common.util.concurrent.ThreadFactoryBuilder;
++import com.google.gson.JsonArray;
++import com.google.gson.JsonObject;
++import com.google.gson.internal.Streams;
++import com.google.gson.stream.JsonWriter;
++import com.mojang.datafixers.util.Either;
+ import it.unimi.dsi.fastutil.objects.ObjectRBTreeSet;
+ import java.lang.ref.Cleaner;
+ import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
- import net.minecraft.nbt.CompoundTag;
- import net.minecraft.network.chat.Component;
+import net.minecraft.server.level.ChunkHolder;
+import net.minecraft.server.level.ChunkMap;
+import net.minecraft.server.level.DistanceManager;
-+import net.minecraft.server.level.ServerChunkCache;
import net.minecraft.server.level.ServerLevel;
+import net.minecraft.server.level.ServerPlayer;
+import net.minecraft.server.level.Ticket;
@@ -244,42 +252,26 @@ index 162aa7718488a74980843944e0d026ccfd5a65a5..4e29c0a983727fc839a4bcde01d32863
+import net.minecraft.world.level.chunk.ChunkAccess;
+import net.minecraft.world.level.chunk.ChunkStatus;
import org.apache.commons.lang.exception.ExceptionUtils;
-+import com.google.gson.JsonArray;
-+import com.google.gson.JsonObject;
-+import com.google.gson.internal.Streams;
-+import com.google.gson.stream.JsonWriter;
- import com.mojang.authlib.GameProfile;
-+import com.mojang.datafixers.util.Either;
-+import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap;
import org.bukkit.Location;
import org.bukkit.block.BlockFace;
- import org.bukkit.craftbukkit.CraftWorld;
-@@ -24,8 +38,11 @@ import org.spigotmc.AsyncCatcher;
+@@ -19,8 +31,11 @@ import org.spigotmc.AsyncCatcher;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
+import java.io.*;
-+import java.util.ArrayList;
++import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Queue;
+import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.LinkedBlockingQueue;
-@@ -541,6 +558,172 @@ public final class MCUtil {
- return null;
+@@ -505,6 +520,163 @@ public final class MCUtil {
+ }
}
+ public static ChunkStatus getChunkStatus(ChunkHolder chunk) {
-+ List<ChunkStatus> statuses = net.minecraft.server.level.ServerChunkCache.CHUNK_STATUSES;
-+ for (int i = statuses.size() - 1; i >= 0; --i) {
-+ ChunkStatus curr = statuses.get(i);
-+ CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> future = chunk.getFutureIfPresentUnchecked(curr);
-+ if (future != ChunkHolder.UNLOADED_CHUNK_FUTURE) {
-+ return curr;
-+ }
-+ }
-+ return null; // unloaded
++ return chunk.getChunkHolderStatus();
+ }
+
+ public static void dumpChunks(File file) throws IOException {
@@ -337,9 +329,8 @@ index 162aa7718488a74980843944e0d026ccfd5a65a5..4e29c0a983727fc839a4bcde01d32863
+
+ ServerLevel world = ((org.bukkit.craftbukkit.CraftWorld)bukkitWorld).getHandle();
+ ChunkMap chunkMap = world.getChunkSource().chunkMap;
-+ Long2ObjectLinkedOpenHashMap<ChunkHolder> visibleChunks = chunkMap.visibleChunkMap;
+ DistanceManager chunkMapDistance = chunkMap.distanceManager;
-+ List<ChunkHolder> allChunks = new ArrayList<>(visibleChunks.values());
++ List<ChunkHolder> allChunks = net.minecraft.server.ChunkSystem.getVisibleChunkHolders(world);
+ List<ServerPlayer> players = world.players;
+
+ int fullLoadedChunks = 0;
@@ -362,7 +353,7 @@ index 162aa7718488a74980843944e0d026ccfd5a65a5..4e29c0a983727fc839a4bcde01d32863
+ worldData.addProperty("view-distance", world.spigotConfig.viewDistance);
+ worldData.addProperty("keep-spawn-loaded", world.keepSpawnInMemory);
+ worldData.addProperty("keep-spawn-loaded-range", world.paperConfig().spawn.keepSpawnLoadedRange * 16);
-+ worldData.addProperty("visible-chunk-count", visibleChunks.size());
++ worldData.addProperty("visible-chunk-count", allChunks.size());
+ worldData.addProperty("loaded-chunk-count", chunkMap.entitiesInLevel.size());
+ worldData.addProperty("verified-fully-loaded-chunks", fullLoadedChunks);
+
@@ -431,7 +422,7 @@ index 162aa7718488a74980843944e0d026ccfd5a65a5..4e29c0a983727fc839a4bcde01d32863
+
+ String fileData = stringWriter.toString();
+
-+ try (PrintStream out = new PrintStream(new FileOutputStream(file), false, "UTF-8")) {
++ try (PrintStream out = new PrintStream(new FileOutputStream(file), false, StandardCharsets.UTF_8)) {
+ out.print(fileData);
+ }
+ }
diff --git a/patches/server/0718-Make-CallbackExecutor-strict-again.patch b/patches/server/0017-Make-CallbackExecutor-strict-again.patch
index 5a1db21f68..e37cf530bb 100644
--- a/patches/server/0718-Make-CallbackExecutor-strict-again.patch
+++ b/patches/server/0017-Make-CallbackExecutor-strict-again.patch
@@ -10,10 +10,10 @@ schedules. Effectively, use the callback executor as a tool of
finding issues rather than hiding these issues.
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
-index b659a058a0b6eb6b1827aacbd703e15fcbb1609c..2418f1c0dc050d224bb866e62f414a55900d9652 100644
+index ea27e6b1340a42c675bc68ed75f100569114be7a..4da0cbe58dad0f66e0d056c71684120514dcac6a 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
-@@ -165,17 +165,28 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -157,17 +157,28 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
public final CallbackExecutor callbackExecutor = new CallbackExecutor();
public static final class CallbackExecutor implements java.util.concurrent.Executor, Runnable {
diff --git a/patches/server/0426-Delay-Chunk-Unloads-based-on-Player-Movement.patch b/patches/server/0018-Delay-Chunk-Unloads-based-on-Player-Movement.patch
index 21c409adc6..bd5e8ce10c 100644
--- a/patches/server/0426-Delay-Chunk-Unloads-based-on-Player-Movement.patch
+++ b/patches/server/0018-Delay-Chunk-Unloads-based-on-Player-Movement.patch
@@ -17,10 +17,10 @@ This allows servers with smaller worlds who do less long distance exploring to s
wasting cpu cycles on saving/unloading/reloading chunks repeatedly.
diff --git a/src/main/java/net/minecraft/server/level/DistanceManager.java b/src/main/java/net/minecraft/server/level/DistanceManager.java
-index 62118348d6fb00f063507debb488e1ff431d139c..9bc956068df3baabb9f8e02ee74a6397de2bf587 100644
+index 6181f675d7addde30f7018b4cd46fe061a14da51..aaf6344d3187ceada947ce6ee0fbba91ca0271a3 100644
--- a/src/main/java/net/minecraft/server/level/DistanceManager.java
+++ b/src/main/java/net/minecraft/server/level/DistanceManager.java
-@@ -212,6 +212,27 @@ public abstract class DistanceManager {
+@@ -198,6 +198,27 @@ public abstract class DistanceManager {
boolean removed = false; // CraftBukkit
if (arraysetsorted.remove(ticket)) {
removed = true; // CraftBukkit
@@ -76,10 +76,10 @@ index ffc43e5d3d0563c9e9c171064511b2c65ddf67e1..f1128f0d4a9a0241ac6c9bc18dd13b43
}
}
diff --git a/src/main/java/net/minecraft/server/level/TicketType.java b/src/main/java/net/minecraft/server/level/TicketType.java
-index 78fbb4c3e52e900956ae0811aaf934c81ee5ea48..8770fe0db46b01e8b608637df4f1a669a3f4cdde 100644
+index 0d536d72ac918fbd403397ff369d10143ee9c204..dfa08dbf025ed702a864280a540e0169b9f33cbd 100644
--- a/src/main/java/net/minecraft/server/level/TicketType.java
+++ b/src/main/java/net/minecraft/server/level/TicketType.java
-@@ -28,6 +28,7 @@ public class TicketType<T> {
+@@ -26,6 +26,7 @@ public class TicketType<T> {
public static final TicketType<ChunkPos> UNKNOWN = TicketType.create("unknown", Comparator.comparingLong(ChunkPos::toLong), 1);
public static final TicketType<Unit> PLUGIN = TicketType.create("plugin", (a, b) -> 0); // CraftBukkit
public static final TicketType<org.bukkit.plugin.Plugin> PLUGIN_TICKET = TicketType.create("plugin_ticket", (plugin1, plugin2) -> plugin1.getClass().getName().compareTo(plugin2.getClass().getName())); // CraftBukkit
diff --git a/patches/server/0252-Asynchronous-chunk-IO-and-loading.patch b/patches/server/0019-Asynchronous-chunk-IO-and-loading.patch
index 2a51a5d5f0..cf7bd1b0ad 100644
--- a/patches/server/0252-Asynchronous-chunk-IO-and-loading.patch
+++ b/patches/server/0019-Asynchronous-chunk-IO-and-loading.patch
@@ -2266,7 +2266,7 @@ index a5e438a834826161c52ca9db57d234d9ff80a591..b8bc1b9b8e8a33df90a963f9f9769292
@Override
diff --git a/src/main/java/net/minecraft/server/Main.java b/src/main/java/net/minecraft/server/Main.java
-index 97b29bcb20e199c2d02457f8025e67e2d4a925fc..8fda43173012ed3134ed1f114143ceaad66cae4a 100644
+index a48a12a31a3d09a9373b688dcc093035f8f8a300..0c59ca1a22449893adcfa851198f057ce69bb7e3 100644
--- a/src/main/java/net/minecraft/server/Main.java
+++ b/src/main/java/net/minecraft/server/Main.java
@@ -245,6 +245,7 @@ public class Main {
@@ -2278,11 +2278,11 @@ index 97b29bcb20e199c2d02457f8025e67e2d4a925fc..8fda43173012ed3134ed1f114143ceaa
DedicatedServer dedicatedserver1 = new DedicatedServer(optionset, config.get(), ops.get(), thread, convertable_conversionsession, resourcepackrepository, worldstem, dedicatedserversettings, DataFixers.getDataFixer(), services, LoggerChunkProgressListener::new);
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
-index 78f7f5603f6949c6aa92726d99e93ebdfea2b637..802b7767dd0878cf6d2e52bea74d5664f7d0664f 100644
+index 53be6189d3fa6a65a09996683913fbbf5133dcb7..d53fb6bba90936c1182b0687d014964cef81694f 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
-@@ -956,7 +956,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
- this.getProfileCache().save(false); // Paper
+@@ -932,7 +932,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+ this.getProfileCache().save();
}
// Spigot end
-
@@ -2291,10 +2291,10 @@ index 78f7f5603f6949c6aa92726d99e93ebdfea2b637..802b7767dd0878cf6d2e52bea74d5664
public String getLocalIp() {
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
-index 7793d6c254c418847d3b5b65e5232bf8192b561b..47cb3be2d778a55bfbe733a9cc2965c8bf28a47a 100644
+index 4da0cbe58dad0f66e0d056c71684120514dcac6a..c3bbaf32373a32417f8b83f386f8cf327c6e0893 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
-@@ -526,6 +526,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -545,6 +545,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
public void close() throws IOException {
try {
this.queueSorter.close();
@@ -2302,7 +2302,32 @@ index 7793d6c254c418847d3b5b65e5232bf8192b561b..47cb3be2d778a55bfbe733a9cc2965c8
this.poiManager.close();
} finally {
super.close();
-@@ -562,7 +563,8 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -553,6 +554,16 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+ }
+
+ protected void saveAllChunks(boolean flush) {
++ // Paper start - do not overload I/O threads with too much work when saving
++ int[] saved = new int[1];
++ int maxAsyncSaves = 50;
++ Runnable onChunkSave = () -> {
++ if (++saved[0] >= maxAsyncSaves) {
++ saved[0] = 0;
++ com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.flush();
++ }
++ };
++ // Paper end - do not overload I/O threads with too much work when saving
+ if (flush) {
+ List<ChunkHolder> list = (List) net.minecraft.server.ChunkSystem.getVisibleChunkHolders(this.level).stream().filter(ChunkHolder::wasAccessibleSinceLastSave).peek(ChunkHolder::refreshAccessibility).collect(Collectors.toList()); // Paper
+ MutableBoolean mutableboolean = new MutableBoolean();
+@@ -574,6 +585,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+ }).filter((ichunkaccess) -> {
+ return ichunkaccess instanceof ImposterProtoChunk || ichunkaccess instanceof LevelChunk;
+ }).filter(this::save).forEach((ichunkaccess) -> {
++ onChunkSave.run(); // Paper - do not overload I/O threads with too much work when saving
+ mutableboolean.setTrue();
+ });
+ } while (mutableboolean.isTrue());
+@@ -581,7 +593,8 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
this.processUnloads(() -> {
return true;
});
@@ -2310,9 +2335,9 @@ index 7793d6c254c418847d3b5b65e5232bf8192b561b..47cb3be2d778a55bfbe733a9cc2965c8
+ //this.flushWorker(); // Paper - nuke IOWorker
+ this.level.asyncChunkTaskManager.flush(); // Paper - flush to preserve behavior compat with pre-async behaviour
} else {
- this.visibleChunkMap.values().forEach(this::saveChunkIfNeeded);
+ net.minecraft.server.ChunkSystem.getVisibleChunkHolders(this.level).forEach(this::saveChunkIfNeeded);
}
-@@ -572,11 +574,15 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -591,11 +604,15 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
protected void tick(BooleanSupplier shouldKeepTicking) {
ProfilerFiller gameprofilerfiller = this.level.getProfiler();
@@ -2328,7 +2353,7 @@ index 7793d6c254c418847d3b5b65e5232bf8192b561b..47cb3be2d778a55bfbe733a9cc2965c8
}
gameprofilerfiller.pop();
-@@ -639,7 +645,16 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -658,7 +675,16 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
((LevelChunk) ichunkaccess).setLoaded(false);
}
@@ -2346,7 +2371,7 @@ index 7793d6c254c418847d3b5b65e5232bf8192b561b..47cb3be2d778a55bfbe733a9cc2965c8
if (this.entitiesInLevel.remove(pos) && ichunkaccess instanceof LevelChunk) {
LevelChunk chunk = (LevelChunk) ichunkaccess;
-@@ -705,32 +720,54 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -727,32 +753,54 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
}
private CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> scheduleChunkLoad(ChunkPos pos) {
@@ -2420,7 +2445,7 @@ index 7793d6c254c418847d3b5b65e5232bf8192b561b..47cb3be2d778a55bfbe733a9cc2965c8
return nbt.contains("Status", 8);
}
-@@ -969,7 +1006,48 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -991,7 +1039,48 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
}
}
@@ -2469,7 +2494,7 @@ index 7793d6c254c418847d3b5b65e5232bf8192b561b..47cb3be2d778a55bfbe733a9cc2965c8
this.poiManager.flush(chunk.getPos());
if (!chunk.isUnsaved()) {
return false;
-@@ -981,7 +1059,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -1003,7 +1092,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
ChunkStatus chunkstatus = chunk.getStatus();
if (chunkstatus.getChunkType() != ChunkStatus.ChunkType.LEVELCHUNK) {
@@ -2478,7 +2503,7 @@ index 7793d6c254c418847d3b5b65e5232bf8192b561b..47cb3be2d778a55bfbe733a9cc2965c8
return false;
}
-@@ -991,9 +1069,15 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -1013,9 +1102,15 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
}
this.level.getProfiler().incrementCounter("chunkSave");
@@ -2496,7 +2521,7 @@ index 7793d6c254c418847d3b5b65e5232bf8192b561b..47cb3be2d778a55bfbe733a9cc2965c8
this.markPosition(chunkcoordintpair, chunkstatus.getChunkType());
return true;
} catch (Exception exception) {
-@@ -1002,6 +1086,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -1023,6 +1118,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
return false;
}
}
@@ -2504,7 +2529,7 @@ index 7793d6c254c418847d3b5b65e5232bf8192b561b..47cb3be2d778a55bfbe733a9cc2965c8
}
private boolean isExistingChunkFull(ChunkPos pos) {
-@@ -1135,6 +1220,35 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -1156,6 +1252,35 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
}
}
@@ -2541,10 +2566,10 @@ index 7793d6c254c418847d3b5b65e5232bf8192b561b..47cb3be2d778a55bfbe733a9cc2965c8
return this.read(chunkPos).thenApplyAsync((optional) -> {
return optional.map((nbttagcompound) -> this.upgradeChunkTag(nbttagcompound, chunkPos)); // CraftBukkit
diff --git a/src/main/java/net/minecraft/server/level/DistanceManager.java b/src/main/java/net/minecraft/server/level/DistanceManager.java
-index f08089b8672454acf8c2309e850466b335248692..ab785bfc29c0b120b7c6fed2d15460c86e020291 100644
+index aaf6344d3187ceada947ce6ee0fbba91ca0271a3..1d6ab658c48bb765f66624f276ec7b05cf33c1d5 100644
--- a/src/main/java/net/minecraft/server/level/DistanceManager.java
+++ b/src/main/java/net/minecraft/server/level/DistanceManager.java
-@@ -384,7 +384,7 @@ public abstract class DistanceManager {
+@@ -402,7 +402,7 @@ public abstract class DistanceManager {
}
public void removeTicketsOnClosing() {
@@ -2554,10 +2579,10 @@ index f08089b8672454acf8c2309e850466b335248692..ab785bfc29c0b120b7c6fed2d15460c8
while (objectiterator.hasNext()) {
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
-index a81644df294c739b72fc638cd06a3976250caa50..d66ec02b09bb7ae46aae8e55f00626139f074ae3 100644
+index 514111ed7fe8aec0d5f15f7a8f157d5872a56e4f..3ff5e35e45a71dc03552dedb65c7338317e9d0a9 100644
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
-@@ -491,10 +491,111 @@ public class ServerChunkCache extends ChunkSource {
+@@ -308,10 +308,111 @@ public class ServerChunkCache extends ChunkSource {
return ret;
}
// Paper end
@@ -2669,7 +2694,7 @@ index a81644df294c739b72fc638cd06a3976250caa50..d66ec02b09bb7ae46aae8e55f0062613
if (Thread.currentThread() != this.mainThread) {
return (ChunkAccess) CompletableFuture.supplyAsync(() -> {
return this.getChunk(x, z, leastStatus, create);
-@@ -517,13 +618,18 @@ public class ServerChunkCache extends ChunkSource {
+@@ -334,13 +435,18 @@ public class ServerChunkCache extends ChunkSource {
}
gameprofilerfiller.incrementCounter("getChunkCacheMiss");
@@ -2689,7 +2714,7 @@ index a81644df294c739b72fc638cd06a3976250caa50..d66ec02b09bb7ae46aae8e55f0062613
this.level.timings.syncChunkLoad.stopTiming(); // Paper
} // Paper
ichunkaccess = (ChunkAccess) ((Either) completablefuture.join()).map((ichunkaccess1) -> {
-@@ -610,6 +716,11 @@ public class ServerChunkCache extends ChunkSource {
+@@ -427,6 +533,11 @@ public class ServerChunkCache extends ChunkSource {
}
private CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> getChunkFutureMainThread(int chunkX, int chunkZ, ChunkStatus leastStatus, boolean create) {
@@ -2701,7 +2726,7 @@ index a81644df294c739b72fc638cd06a3976250caa50..d66ec02b09bb7ae46aae8e55f0062613
ChunkPos chunkcoordintpair = new ChunkPos(chunkX, chunkZ);
long k = chunkcoordintpair.toLong();
int l = 33 + ChunkStatus.getDistance(leastStatus);
-@@ -1033,11 +1144,12 @@ public class ServerChunkCache extends ChunkSource {
+@@ -841,11 +952,12 @@ public class ServerChunkCache extends ChunkSource {
// CraftBukkit start - process pending Chunk loadCallback() and unloadCallback() after each run task
public boolean pollTask() {
try {
@@ -2716,10 +2741,10 @@ index a81644df294c739b72fc638cd06a3976250caa50..d66ec02b09bb7ae46aae8e55f0062613
} finally {
chunkMap.callbackExecutor.run();
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index 6e804d560b44d8bfd0b184632e49d52fdb7879fb..02d4211b9c3a485ac23cce199d7edc7e4d445067 100644
+index 99d44faab5b5da244fdc170c73d73723c174c8fd..2f7646e2bcc9622d8579eec25b56615da5a84d06 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
-@@ -317,6 +317,78 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -315,6 +315,78 @@ public class ServerLevel extends Level implements WorldGenLevel {
}
}
}
@@ -2798,7 +2823,7 @@ index 6e804d560b44d8bfd0b184632e49d52fdb7879fb..02d4211b9c3a485ac23cce199d7edc7e
// Paper end
// Add env and gen to constructor, IWorldDataServer -> WorldDataServer
-@@ -399,6 +471,8 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -397,6 +469,8 @@ public class ServerLevel extends Level implements WorldGenLevel {
this.sleepStatus = new SleepStatus();
this.getCraftServer().addWorld(this.getWorld()); // CraftBukkit
@@ -2808,7 +2833,7 @@ index 6e804d560b44d8bfd0b184632e49d52fdb7879fb..02d4211b9c3a485ac23cce199d7edc7e
public void setWeatherParameters(int clearDuration, int rainDuration, boolean raining, boolean thundering) {
diff --git a/src/main/java/net/minecraft/server/level/TicketType.java b/src/main/java/net/minecraft/server/level/TicketType.java
-index 0d536d72ac918fbd403397ff369d10143ee9c204..be677d437d17b74c6188ce1bd5fc6fdc228fd92f 100644
+index dfa08dbf025ed702a864280a540e0169b9f33cbd..10fa6cec911950f72407ae7f45c8cf48caa9421a 100644
--- a/src/main/java/net/minecraft/server/level/TicketType.java
+++ b/src/main/java/net/minecraft/server/level/TicketType.java
@@ -8,6 +8,7 @@ import net.minecraft.world.level.ChunkPos;
@@ -2820,11 +2845,11 @@ index 0d536d72ac918fbd403397ff369d10143ee9c204..be677d437d17b74c6188ce1bd5fc6fdc
private final String name;
private final Comparator<T> comparator;
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-index 0bac1fa4637d7132871b8f57b0431724bc9aa8c1..d991354d65305ab7d02666f7c3362e4136c3f6af 100644
+index cdc24defe649644ceade1c6cfcfe20c29ca936c1..5072d4dc1f7f77c61e3cc72c1101cb95f6596ce7 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-@@ -799,6 +799,13 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
- server.scheduleOnMain(() -> this.disconnect(Component.translatable("disconnect.spam", new Object[0]))); // Paper
+@@ -784,6 +784,13 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
+ this.disconnect(Component.translatable("disconnect.spam"));
return;
}
+ // Paper start
@@ -2835,8 +2860,8 @@ index 0bac1fa4637d7132871b8f57b0431724bc9aa8c1..d991354d65305ab7d02666f7c3362e41
+ }
+ // Paper end
// CraftBukkit end
- // Paper start - async tab completion
- TAB_COMPLETE_EXECUTOR.execute(() -> {
+ StringReader stringreader = new StringReader(packet.getCommand());
+
diff --git a/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java b/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java
index 821052e93ee753db6aaf499bbf39dc30598fe72f..2955c1ee153c410ea45fe367bac8597621c9bbd0 100644
--- a/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java
@@ -3285,7 +3310,7 @@ index c56946f86565ad1ac41bb7b655c113f648d2f539..694778b5c23dbe9c8603c3483476b525
}
}
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java
-index 2d74ab966a1291895b6248a67a31fe4802b3773f..038e2177182c94baa4af24f9111cf155ec342dfe 100644
+index d51bafd2f5a763b8a49c835ab74a7cf60caa1ab6..7412da51c2eae70f17f4883f7223303d570c8402 100644
--- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java
@@ -44,6 +44,7 @@ public class RegionFile implements AutoCloseable {
@@ -3305,7 +3330,7 @@ index 2d74ab966a1291895b6248a67a31fe4802b3773f..038e2177182c94baa4af24f9111cf155
int i = this.getOffset(pos);
if (i == 0) {
-@@ -395,6 +396,11 @@ public class RegionFile implements AutoCloseable {
+@@ -393,6 +394,11 @@ public class RegionFile implements AutoCloseable {
}
public void close() throws IOException {
@@ -3317,7 +3342,7 @@ index 2d74ab966a1291895b6248a67a31fe4802b3773f..038e2177182c94baa4af24f9111cf155
try {
this.padToFullSector();
} finally {
-@@ -404,6 +410,10 @@ public class RegionFile implements AutoCloseable {
+@@ -402,6 +408,10 @@ public class RegionFile implements AutoCloseable {
this.file.close();
}
}
@@ -3329,7 +3354,7 @@ index 2d74ab966a1291895b6248a67a31fe4802b3773f..038e2177182c94baa4af24f9111cf155
}
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
-index 5a35e5040726a981ae91f018f05b91c178a54ba0..9d7adf17851202adf03bf9feff3577069e324bc6 100644
+index 8ba1c073387fa21a20bd42a873ec3cc314eae64e..6fa0bc18ab05b9fb05521f46c5dadb695f1ec05b 100644
--- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
@@ -29,11 +29,32 @@ public class RegionFileStorage implements AutoCloseable {
@@ -3365,7 +3390,7 @@ index 5a35e5040726a981ae91f018f05b91c178a54ba0..9d7adf17851202adf03bf9feff357706
+ // Paper end
return regionfile;
} else {
- if (this.regionCache.size() >= io.papermc.paper.configuration.GlobalConfiguration.get().misc.regionFileCacheSize) { // Paper - configurable
+ if (this.regionCache.size() >= 256) {
@@ -48,6 +69,12 @@ public class RegionFileStorage implements AutoCloseable {
RegionFile regionfile1 = new RegionFile(path1, this.folder, this.sync);
@@ -3410,13 +3435,13 @@ index 5a35e5040726a981ae91f018f05b91c178a54ba0..9d7adf17851202adf03bf9feff357706
- RegionFile regionfile = this.getRegionFile(pos, false); // CraftBukkit
+ RegionFile regionfile = this.getRegionFile(pos, false, true); // CraftBukkit // Paper
+ try { // Paper
- int attempts = 0; Exception laste = null; while (attempts++ < 5) { try { // Paper
if (nbt == null) {
-@@ -169,9 +201,12 @@ public class RegionFileStorage implements AutoCloseable {
- net.minecraft.server.MinecraftServer.LOGGER.error("Failed to save chunk", laste);
+ regionfile.clear(pos);
+@@ -156,9 +188,12 @@ public class RegionFileStorage implements AutoCloseable {
+ }
}
- // Paper end
+
+ } finally { // Paper start
+ regionfile.fileLock.unlock();
+ } // Paper end
@@ -3427,7 +3452,7 @@ index 5a35e5040726a981ae91f018f05b91c178a54ba0..9d7adf17851202adf03bf9feff357706
ExceptionCollector<IOException> exceptionsuppressor = new ExceptionCollector<>();
ObjectIterator objectiterator = this.regionCache.values().iterator();
-@@ -188,7 +223,7 @@ public class RegionFileStorage implements AutoCloseable {
+@@ -175,7 +210,7 @@ public class RegionFileStorage implements AutoCloseable {
exceptionsuppressor.throwIfPresent();
}
@@ -3554,95 +3579,14 @@ index 8a4750dd8f604062c4ea452f7b97b05a0c8d583a..678bd36581ead3a225e3a6e24b78e5db
}
+ // Paper end
}
-diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-index 153c2e8bc317d9bff834645102235434e82716e1..0d939dc855d4e03df9a95d318e769d842892d46d 100644
---- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-@@ -1956,6 +1956,34 @@ public class CraftWorld extends CraftRegionAccessor implements World {
- public DragonBattle getEnderDragonBattle() {
- return (this.getHandle().dragonFight() == null) ? null : new CraftDragonBattle(this.getHandle().dragonFight());
- }
-+ // Paper start
-+ @Override
-+ public java.util.concurrent.CompletableFuture<Chunk> getChunkAtAsync(int x, int z, boolean gen, boolean urgent) {
-+ if (Bukkit.isPrimaryThread()) {
-+ net.minecraft.world.level.chunk.LevelChunk immediate = this.world.getChunkSource().getChunkAtIfLoadedImmediately(x, z);
-+ if (immediate != null) {
-+ return java.util.concurrent.CompletableFuture.completedFuture(immediate.getBukkitChunk());
-+ }
-+ } else {
-+ java.util.concurrent.CompletableFuture<Chunk> future = new java.util.concurrent.CompletableFuture<Chunk>();
-+ world.getServer().execute(() -> {
-+ getChunkAtAsync(x, z, gen, urgent).whenComplete((chunk, err) -> {
-+ if (err != null) {
-+ future.completeExceptionally(err);
-+ } else {
-+ future.complete(chunk);
-+ }
-+ });
-+ });
-+ return future;
-+ }
-+
-+ return this.world.getChunkSource().getChunkAtAsynchronously(x, z, gen, urgent).thenComposeAsync((either) -> {
-+ net.minecraft.world.level.chunk.LevelChunk chunk = (net.minecraft.world.level.chunk.LevelChunk) either.left().orElse(null);
-+ return java.util.concurrent.CompletableFuture.completedFuture(chunk == null ? null : chunk.getBukkitChunk());
-+ }, net.minecraft.server.MinecraftServer.getServer());
-+ }
-+ // Paper end
-
- @Override
- public PersistentDataContainer getPersistentDataContainer() {
-diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
-index e6b75dfa1a59c9f1f6afde7b4538abf8d51b7261..41920b979ab259fc27a57dde64abdba8c3be3185 100644
---- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
-+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
-@@ -533,6 +533,37 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
- this.entity.setYHeadRot(yaw);
- }
-
-+ // Paper start
-+ @Override
-+ public java.util.concurrent.CompletableFuture<Boolean> teleportAsync(Location location, TeleportCause cause) {
-+ Preconditions.checkArgument(location != null, "location");
-+ location.checkFinite();
-+ Location locationClone = location.clone(); // clone so we don't need to worry about mutations after this call.
-+
-+ net.minecraft.server.level.ServerLevel world = ((CraftWorld)locationClone.getWorld()).getHandle();
-+ java.util.concurrent.CompletableFuture<Boolean> ret = new java.util.concurrent.CompletableFuture<>();
-+
-+ world.loadChunksForMoveAsync(getHandle().getBoundingBoxAt(locationClone.getX(), locationClone.getY(), locationClone.getZ()), location.getX(), location.getZ(), (list) -> {
-+ net.minecraft.server.level.ServerChunkCache chunkProviderServer = world.getChunkSource();
-+ for (net.minecraft.world.level.chunk.ChunkAccess chunk : list) {
-+ chunkProviderServer.addTicketAtLevel(net.minecraft.server.level.TicketType.POST_TELEPORT, chunk.getPos(), 33, CraftEntity.this.getEntityId());
-+ }
-+ net.minecraft.server.MinecraftServer.getServer().scheduleOnMain(() -> {
-+ try {
-+ ret.complete(CraftEntity.this.teleport(locationClone, cause) ? Boolean.TRUE : Boolean.FALSE);
-+ } catch (Throwable throwable) {
-+ if (throwable instanceof ThreadDeath) {
-+ throw (ThreadDeath)throwable;
-+ }
-+ ret.completeExceptionally(throwable);
-+ }
-+ });
-+ });
-+
-+ return ret;
-+ }
-+ // Paper end
-+
- @Override
- public boolean teleport(Location location) {
- return this.teleport(location, TeleportCause.PLUGIN);
diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/spigotmc/WatchdogThread.java
-index 06efdd7aa6d35a670e81c4f303618a7ba301396a..e62f085de1678568d422ef0eda5b9bfbd8b4d556 100644
+index 335120afc88a8fc1543c2e6df516fd728e3ab032..581cde7a74e00bee1ce69086132d5f871d206399 100644
--- a/src/main/java/org/spigotmc/WatchdogThread.java
+++ b/src/main/java/org/spigotmc/WatchdogThread.java
-@@ -116,6 +116,7 @@ public class WatchdogThread extends Thread
- // Paper end - Different message for short timeout
+@@ -83,6 +83,7 @@ public class WatchdogThread extends Thread
+ //
log.log( Level.SEVERE, "------------------------------" );
- log.log( Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Paper!):" ); // Paper
+ log.log( Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Spigot!):" );
+ com.destroystokyo.paper.io.chunk.ChunkTaskManager.dumpAllChunkLoadInfo(); // Paper
WatchdogThread.dumpThread( ManagementFactory.getThreadMXBean().getThreadInfo( MinecraftServer.getServer().serverThread.getId(), Integer.MAX_VALUE ), log );
log.log( Level.SEVERE, "------------------------------" );
diff --git a/patches/server/0461-Implement-Chunk-Priority-Urgency-System-for-Chunks.patch b/patches/server/0020-Implement-Chunk-Priority-Urgency-System-for-Chunks.patch
index 71afd9f90e..0f3896c168 100644
--- a/patches/server/0461-Implement-Chunk-Priority-Urgency-System-for-Chunks.patch
+++ b/patches/server/0020-Implement-Chunk-Priority-Urgency-System-for-Chunks.patch
@@ -67,11 +67,95 @@ index af40e473521f408aa0e112953c43bdbce164a48b..68860a3b6db2aa50373d71aec9502c18
}
}
+diff --git a/src/main/java/net/minecraft/server/ChunkSystem.java b/src/main/java/net/minecraft/server/ChunkSystem.java
+index 7f76c304f5eb3c2f27b348918588ab67b795b1ba..1b1bfd5f92f85f46ad9661a0a64a2a1b4c33a80d 100644
+--- a/src/main/java/net/minecraft/server/ChunkSystem.java
++++ b/src/main/java/net/minecraft/server/ChunkSystem.java
+@@ -55,6 +55,19 @@ public final class ChunkSystem {
+
+ static final TicketType<Long> CHUNK_LOAD = TicketType.create("chunk_load", Long::compareTo);
+
++ // Paper start - priority
++ private static int getPriorityBoost(final PrioritisedExecutor.Priority priority) {
++ if (priority.isLowerOrEqualPriority(PrioritisedExecutor.Priority.NORMAL)) {
++ return 0;
++ }
++
++ int dist = PrioritisedExecutor.Priority.BLOCKING.ordinal() - PrioritisedExecutor.Priority.NORMAL.ordinal();
++
++
++ return (net.minecraft.server.level.DistanceManager.URGENT_PRIORITY * (priority.ordinal() - PrioritisedExecutor.Priority.NORMAL.ordinal())) / dist;
++ }
++ // Paper end - priority
++
+ private static long chunkLoadCounter = 0L;
+ public static void scheduleChunkLoad(final ServerLevel level, final int chunkX, final int chunkZ, final ChunkStatus toStatus,
+ final boolean addTicket, final PrioritisedExecutor.Priority priority, final Consumer<ChunkAccess> onComplete) {
+@@ -68,12 +81,19 @@ public final class ChunkSystem {
+ final int minLevel = 33 + ChunkStatus.getDistance(toStatus);
+ final Long chunkReference = addTicket ? Long.valueOf(++chunkLoadCounter) : null;
+ final ChunkPos chunkPos = new ChunkPos(chunkX, chunkZ);
++ final int priorityBoost = getPriorityBoost(priority);
+
+ if (addTicket) {
+ level.chunkSource.addTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel, chunkReference);
+ }
+ level.chunkSource.runDistanceManagerUpdates();
+
++ if (priorityBoost == net.minecraft.server.level.DistanceManager.URGENT_PRIORITY) {
++ level.chunkSource.markUrgent(chunkPos);
++ } else if (priorityBoost != 0) {
++ level.chunkSource.markHighPriority(chunkPos, priorityBoost);
++ }
++
+ final Consumer<ChunkAccess> loadCallback = (final ChunkAccess chunk) -> {
+ try {
+ if (onComplete != null) {
+@@ -89,6 +109,11 @@ public final class ChunkSystem {
+ level.chunkSource.addTicketAtLevel(TicketType.UNKNOWN, chunkPos, minLevel, chunkPos);
+ level.chunkSource.removeTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel, chunkReference);
+ }
++ if (priorityBoost == net.minecraft.server.level.DistanceManager.URGENT_PRIORITY) {
++ level.chunkSource.clearUrgent(chunkPos);
++ } else if (priorityBoost != 0) {
++ level.chunkSource.clearPriorityTickets(chunkPos);
++ }
+ }
+ };
+
+@@ -135,12 +160,17 @@ public final class ChunkSystem {
+ final int radius = toStatus.ordinal() - 1;
+ final Long chunkReference = addTicket ? Long.valueOf(++chunkLoadCounter) : null;
+ final ChunkPos chunkPos = new ChunkPos(chunkX, chunkZ);
++ final int priorityBoost = getPriorityBoost(priority);
+
+ if (addTicket) {
+ level.chunkSource.addTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel, chunkReference);
+ }
+ level.chunkSource.runDistanceManagerUpdates();
+
++ if (priorityBoost != 0) {
++ level.chunkSource.markAreaHighPriority(chunkPos, priorityBoost, radius);
++ }
++
+ final Consumer<LevelChunk> loadCallback = (final LevelChunk chunk) -> {
+ try {
+ if (onComplete != null) {
+@@ -156,6 +186,9 @@ public final class ChunkSystem {
+ level.chunkSource.addTicketAtLevel(TicketType.UNKNOWN, chunkPos, minLevel, chunkPos);
+ level.chunkSource.removeTicketAtLevel(CHUNK_LOAD, chunkPos, minLevel, chunkReference);
+ }
++ if (priorityBoost != 0) {
++ level.chunkSource.clearAreaPriorityTickets(chunkPos, radius);
++ }
+ }
+ };
+
diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java
-index 4e29c0a983727fc839a4bcde01d3286396b3587d..613988c9ea892ab15516e1c8b4f376d52415ae34 100644
+index 2e56c52e3ee45b0304a9e6a5eab863ef96b2aab0..5eb6ce20ee17d87db0f6c2dcee96d6d0891d6c50 100644
--- a/src/main/java/net/minecraft/server/MCUtil.java
+++ b/src/main/java/net/minecraft/server/MCUtil.java
-@@ -681,6 +681,7 @@ public final class MCUtil {
+@@ -634,6 +634,7 @@ public final class MCUtil {
chunkData.addProperty("x", playerChunk.pos.x);
chunkData.addProperty("z", playerChunk.pos.z);
chunkData.addProperty("ticket-level", playerChunk.getTicketLevel());
@@ -80,7 +164,7 @@ index 4e29c0a983727fc839a4bcde01d3286396b3587d..613988c9ea892ab15516e1c8b4f376d5
chunkData.addProperty("queued-for-unload", chunkMap.toDrop.contains(playerChunk.pos.longKey));
chunkData.addProperty("status", status == null ? "unloaded" : status.toString());
diff --git a/src/main/java/net/minecraft/server/level/ChunkHolder.java b/src/main/java/net/minecraft/server/level/ChunkHolder.java
-index 36a9d52d9af3bc398010c52dc16ab23e53f2702a..ece4cd0de061969d4d2f07560e6cf38e631098b3 100644
+index e30893d6cbe3b42338d04453d0f452babeb61d8a..a52932d665ca45a5e066d7cef0ec0313d1c3f69f 100644
--- a/src/main/java/net/minecraft/server/level/ChunkHolder.java
+++ b/src/main/java/net/minecraft/server/level/ChunkHolder.java
@@ -60,7 +60,7 @@ public class ChunkHolder {
@@ -100,7 +184,7 @@ index 36a9d52d9af3bc398010c52dc16ab23e53f2702a..ece4cd0de061969d4d2f07560e6cf38e
boolean isUpdateQueued = false; // Paper
private final ChunkMap chunkMap; // Paper
-@@ -448,12 +449,18 @@ public class ChunkHolder {
+@@ -438,12 +439,18 @@ public class ChunkHolder {
});
}
@@ -119,7 +203,7 @@ index 36a9d52d9af3bc398010c52dc16ab23e53f2702a..ece4cd0de061969d4d2f07560e6cf38e
ChunkStatus chunkstatus = ChunkHolder.getStatus(this.oldTicketLevel);
ChunkStatus chunkstatus1 = ChunkHolder.getStatus(this.ticketLevel);
boolean flag = this.oldTicketLevel <= ChunkMap.MAX_CHUNK_DISTANCE;
-@@ -464,9 +471,22 @@ public class ChunkHolder {
+@@ -454,9 +461,22 @@ public class ChunkHolder {
// ChunkUnloadEvent: Called before the chunk is unloaded: isChunkLoaded is still true and chunk can still be modified by plugins.
if (playerchunk_state.isOrAfter(ChunkHolder.FullChunkStatus.BORDER) && !playerchunk_state1.isOrAfter(ChunkHolder.FullChunkStatus.BORDER)) {
this.getFutureIfPresentUnchecked(ChunkStatus.FULL).thenAccept((either) -> {
@@ -143,22 +227,21 @@ index 36a9d52d9af3bc398010c52dc16ab23e53f2702a..ece4cd0de061969d4d2f07560e6cf38e
// Minecraft will apply the chunks tick lists to the world once the chunk got loaded, and then store the tick
// lists again inside the chunk once the chunk becomes inaccessible and set the chunk's needsSaving flag.
// These actions may however happen deferred, so we manually set the needsSaving flag already here.
-@@ -523,12 +543,14 @@ public class ChunkHolder {
+@@ -501,11 +521,13 @@ public class ChunkHolder {
this.scheduleFullChunkPromotion(chunkStorage, this.fullChunkFuture, executor, ChunkHolder.FullChunkStatus.BORDER);
// Paper start - cache ticking ready status
this.fullChunkFuture.thenAccept(either -> {
+ io.papermc.paper.util.TickThread.ensureTickThread("Async full chunk future completion"); // Paper
final Optional<LevelChunk> left = either.left();
if (left.isPresent() && ChunkHolder.this.fullChunkCreateCount == expectCreateCount) {
- // note: Here is a very good place to add callbacks to logic waiting on this.
LevelChunk fullChunk = either.left().get();
ChunkHolder.this.isFullChunkReady = true;
- fullChunk.playerChunk = ChunkHolder.this;
-+ this.chunkMap.distanceManager.clearPriorityTickets(pos);
+ net.minecraft.server.ChunkSystem.onChunkBorder(fullChunk, this);
++ this.chunkMap.distanceManager.clearPriorityTickets(pos); // Paper - chunk priority
}
});
this.updateChunkToSave(this.fullChunkFuture, "full");
-@@ -549,6 +571,7 @@ public class ChunkHolder {
+@@ -531,6 +553,7 @@ public class ChunkHolder {
this.scheduleFullChunkPromotion(chunkStorage, this.tickingChunkFuture, executor, ChunkHolder.FullChunkStatus.TICKING);
// Paper start - cache ticking ready status
this.tickingChunkFuture.thenAccept(either -> {
@@ -166,15 +249,15 @@ index 36a9d52d9af3bc398010c52dc16ab23e53f2702a..ece4cd0de061969d4d2f07560e6cf38e
either.ifLeft(chunk -> {
// note: Here is a very good place to add callbacks to logic waiting on this.
ChunkHolder.this.isTickingReady = true;
-@@ -584,6 +607,7 @@ public class ChunkHolder {
+@@ -563,6 +586,7 @@ public class ChunkHolder {
this.scheduleFullChunkPromotion(chunkStorage, this.entityTickingChunkFuture, executor, ChunkHolder.FullChunkStatus.ENTITY_TICKING);
// Paper start - cache ticking ready status
this.entityTickingChunkFuture.thenAccept(either -> {
+ io.papermc.paper.util.TickThread.ensureTickThread("Async full chunk future completion"); // Paper
either.ifLeft(chunk -> {
ChunkHolder.this.isEntityTickingReady = true;
- // Paper start - entity ticking chunk set
-@@ -610,16 +634,45 @@ public class ChunkHolder {
+ net.minecraft.server.ChunkSystem.onChunkEntityTicking(chunk, this);
+@@ -586,16 +610,45 @@ public class ChunkHolder {
this.demoteFullChunk(chunkStorage, playerchunk_state1);
}
@@ -223,7 +306,7 @@ index 36a9d52d9af3bc398010c52dc16ab23e53f2702a..ece4cd0de061969d4d2f07560e6cf38e
});
}
}).exceptionally((throwable) -> {
-@@ -744,7 +797,134 @@ public class ChunkHolder {
+@@ -696,7 +749,134 @@ public class ChunkHolder {
};
}
@@ -360,7 +443,7 @@ index 36a9d52d9af3bc398010c52dc16ab23e53f2702a..ece4cd0de061969d4d2f07560e6cf38e
return this.isEntityTickingReady;
}
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
-index 4d74eb7883c72fb42275fc5358917244bb36181d..7b1781faed02a5b5fa37ca6f079d1fb620315c80 100644
+index c3bbaf32373a32417f8b83f386f8cf327c6e0893..46bfaf04867d913c1782d851de101d913376c63a 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -131,6 +131,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
@@ -371,7 +454,7 @@ index 4d74eb7883c72fb42275fc5358917244bb36181d..7b1781faed02a5b5fa37ca6f079d1fb6
public ChunkGenerator generator;
private RandomState randomState;
public final Supplier<DimensionDataStorage> overworldDataStorage;
-@@ -334,6 +335,15 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -267,6 +268,15 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
}
this.mainThreadExecutor = mainThreadExecutor;
@@ -387,7 +470,7 @@ index 4d74eb7883c72fb42275fc5358917244bb36181d..7b1781faed02a5b5fa37ca6f079d1fb6
ProcessorMailbox<Runnable> threadedmailbox = ProcessorMailbox.create(executor, "worldgen");
Objects.requireNonNull(mainThreadExecutor);
-@@ -449,6 +459,37 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -309,6 +319,37 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
});
}
@@ -422,10 +505,10 @@ index 4d74eb7883c72fb42275fc5358917244bb36181d..7b1781faed02a5b5fa37ca6f079d1fb6
+ }
+ // Paper end
+
- // Paper start
- public void updatePlayerMobTypeMap(Entity entity) {
- if (!this.level.paperConfig().entities.spawning.perPlayerMobSpawns) {
-@@ -559,6 +600,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+ private static double euclideanDistanceSquared(ChunkPos pos, Entity entity) {
+ double d0 = (double) SectionPos.sectionToBlockCoord(pos.x, 8);
+ double d1 = (double) SectionPos.sectionToBlockCoord(pos.z, 8);
+@@ -399,6 +440,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
List<ChunkHolder> list1 = new ArrayList();
int j = centerChunk.x;
int k = centerChunk.z;
@@ -433,7 +516,7 @@ index 4d74eb7883c72fb42275fc5358917244bb36181d..7b1781faed02a5b5fa37ca6f079d1fb6
for (int l = -margin; l <= margin; ++l) {
for (int i1 = -margin; i1 <= margin; ++i1) {
-@@ -577,6 +619,14 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -417,6 +459,14 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
ChunkStatus chunkstatus = (ChunkStatus) distanceToStatus.apply(j1);
CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> completablefuture = playerchunk.getOrScheduleFuture(chunkstatus, this);
@@ -448,7 +531,7 @@ index 4d74eb7883c72fb42275fc5358917244bb36181d..7b1781faed02a5b5fa37ca6f079d1fb6
list1.add(playerchunk);
list.add(completablefuture);
-@@ -934,11 +984,19 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -733,11 +783,19 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
if (requiredStatus == ChunkStatus.EMPTY) {
return this.scheduleChunkLoad(chunkcoordintpair);
} else {
@@ -469,7 +552,7 @@ index 4d74eb7883c72fb42275fc5358917244bb36181d..7b1781faed02a5b5fa37ca6f079d1fb6
if (optional.isPresent() && ((ChunkAccess) optional.get()).getStatus().isOrAfter(requiredStatus)) {
CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> completablefuture = requiredStatus.load(this.level, this.structureTemplateManager, this.lightEngine, (ichunkaccess) -> {
-@@ -950,6 +1008,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -749,6 +807,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
} else {
return this.scheduleChunkGeneration(holder, requiredStatus);
}
@@ -477,7 +560,7 @@ index 4d74eb7883c72fb42275fc5358917244bb36181d..7b1781faed02a5b5fa37ca6f079d1fb6
}
}
-@@ -989,14 +1048,24 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -788,14 +847,24 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
};
CompletableFuture<CompoundTag> chunkSaveFuture = this.level.asyncChunkTaskManager.getChunkSaveFuture(pos.x, pos.z);
@@ -507,7 +590,7 @@ index 4d74eb7883c72fb42275fc5358917244bb36181d..7b1781faed02a5b5fa37ca6f079d1fb6
return ret;
// Paper end - Async chunk io
}
-@@ -1075,7 +1144,10 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -874,7 +943,10 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
this.releaseLightTicket(chunkcoordintpair);
return CompletableFuture.completedFuture(Either.right(playerchunk_failure));
});
@@ -519,7 +602,7 @@ index 4d74eb7883c72fb42275fc5358917244bb36181d..7b1781faed02a5b5fa37ca6f079d1fb6
}
protected void releaseLightTicket(ChunkPos pos) {
-@@ -1159,7 +1231,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -957,7 +1029,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
long i = chunkHolder.getPos().toLong();
Objects.requireNonNull(chunkHolder);
@@ -529,10 +612,10 @@ index 4d74eb7883c72fb42275fc5358917244bb36181d..7b1781faed02a5b5fa37ca6f079d1fb6
}
diff --git a/src/main/java/net/minecraft/server/level/DistanceManager.java b/src/main/java/net/minecraft/server/level/DistanceManager.java
-index 9bc956068df3baabb9f8e02ee74a6397de2bf587..b2df5e18ce5260a9781052db7afb0b9786fb887c 100644
+index 1d6ab658c48bb765f66624f276ec7b05cf33c1d5..b9b56068cdacd984f873cfb2a06a312e9912893d 100644
--- a/src/main/java/net/minecraft/server/level/DistanceManager.java
+++ b/src/main/java/net/minecraft/server/level/DistanceManager.java
-@@ -128,6 +128,7 @@ public abstract class DistanceManager {
+@@ -114,6 +114,7 @@ public abstract class DistanceManager {
}
private static int getTicketLevelAt(SortedArraySet<Ticket<?>> tickets) {
@@ -540,15 +623,15 @@ index 9bc956068df3baabb9f8e02ee74a6397de2bf587..b2df5e18ce5260a9781052db7afb0b97
return !tickets.isEmpty() ? ((Ticket) tickets.first()).getTicketLevel() : ChunkMap.MAX_CHUNK_DISTANCE + 1;
}
-@@ -142,6 +143,7 @@ public abstract class DistanceManager {
+@@ -128,6 +129,7 @@ public abstract class DistanceManager {
public boolean runAllUpdates(ChunkMap chunkStorage) {
- //this.f.a(); // Paper - no longer used
+ this.naturalSpawnChunkCounter.runAllUpdates();
this.tickingTicketsTracker.runAllUpdates();
+ org.spigotmc.AsyncCatcher.catchOp("DistanceManagerTick"); // Paper
this.playerTicketManager.runAllUpdates();
int i = Integer.MAX_VALUE - this.ticketTracker.runDistanceUpdates(Integer.MAX_VALUE);
boolean flag = i != 0;
-@@ -152,11 +154,13 @@ public abstract class DistanceManager {
+@@ -138,11 +140,13 @@ public abstract class DistanceManager {
// Paper start
if (!this.pendingChunkUpdates.isEmpty()) {
@@ -562,7 +645,7 @@ index 9bc956068df3baabb9f8e02ee74a6397de2bf587..b2df5e18ce5260a9781052db7afb0b97
// Paper end
return true;
} else {
-@@ -192,8 +196,10 @@ public abstract class DistanceManager {
+@@ -178,8 +182,10 @@ public abstract class DistanceManager {
return flag;
}
}
@@ -573,7 +656,7 @@ index 9bc956068df3baabb9f8e02ee74a6397de2bf587..b2df5e18ce5260a9781052db7afb0b97
SortedArraySet<Ticket<?>> arraysetsorted = this.getTickets(i);
int j = DistanceManager.getTicketLevelAt(arraysetsorted);
Ticket<?> ticket1 = (Ticket) arraysetsorted.addOrGet(ticket);
-@@ -207,7 +213,9 @@ public abstract class DistanceManager {
+@@ -193,7 +199,9 @@ public abstract class DistanceManager {
}
boolean removeTicket(long i, Ticket<?> ticket) { // CraftBukkit - void -> boolean
@@ -583,7 +666,7 @@ index 9bc956068df3baabb9f8e02ee74a6397de2bf587..b2df5e18ce5260a9781052db7afb0b97
boolean removed = false; // CraftBukkit
if (arraysetsorted.remove(ticket)) {
-@@ -239,7 +247,12 @@ public abstract class DistanceManager {
+@@ -225,7 +233,12 @@ public abstract class DistanceManager {
this.tickets.remove(i);
}
@@ -597,7 +680,7 @@ index 9bc956068df3baabb9f8e02ee74a6397de2bf587..b2df5e18ce5260a9781052db7afb0b97
return removed; // CraftBukkit
}
-@@ -289,6 +302,112 @@ public abstract class DistanceManager {
+@@ -275,6 +288,112 @@ public abstract class DistanceManager {
});
}
@@ -711,10 +794,10 @@ index 9bc956068df3baabb9f8e02ee74a6397de2bf587..b2df5e18ce5260a9781052db7afb0b97
Ticket<ChunkPos> ticket = new Ticket<>(TicketType.FORCED, 31, pos);
long i = pos.toLong();
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
-index 585892f19bc0aea89889a358c0407f2975b9efe5..918fda0fbbafa39ce0f421dcaf10f8dcf1e5dabb 100644
+index 3ff5e35e45a71dc03552dedb65c7338317e9d0a9..2400212e65c72d3ce6604b3cf200db0ae7032f2a 100644
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
-@@ -590,6 +590,26 @@ public class ServerChunkCache extends ChunkSource {
+@@ -407,6 +407,30 @@ public class ServerChunkCache extends ChunkSource {
return CompletableFuture.completedFuture(either);
}, this.mainThreadProcessor);
}
@@ -738,10 +821,14 @@ index 585892f19bc0aea89889a358c0407f2975b9efe5..918fda0fbbafa39ce0f421dcaf10f8dc
+ public void clearPriorityTickets(ChunkPos coords) {
+ this.distanceManager.clearPriorityTickets(coords);
+ }
++
++ public void clearUrgent(ChunkPos coords) {
++ this.distanceManager.clearUrgent(coords);
++ }
// Paper end - async chunk io
@Nullable
-@@ -630,6 +650,8 @@ public class ServerChunkCache extends ChunkSource {
+@@ -441,6 +465,8 @@ public class ServerChunkCache extends ChunkSource {
Objects.requireNonNull(completablefuture);
if (!completablefuture.isDone()) { // Paper
// Paper start - async chunk io/loading
@@ -750,7 +837,7 @@ index 585892f19bc0aea89889a358c0407f2975b9efe5..918fda0fbbafa39ce0f421dcaf10f8dc
this.level.asyncChunkTaskManager.raisePriority(x1, z1, com.destroystokyo.paper.io.PrioritizedTaskQueue.HIGHEST_PRIORITY);
com.destroystokyo.paper.io.chunk.ChunkTaskManager.pushChunkWait(this.level, x1, z1);
// Paper end
-@@ -638,6 +660,8 @@ public class ServerChunkCache extends ChunkSource {
+@@ -448,6 +474,8 @@ public class ServerChunkCache extends ChunkSource {
chunkproviderserver_b.managedBlock(completablefuture::isDone);
com.destroystokyo.paper.io.chunk.ChunkTaskManager.popChunkWait(); // Paper - async chunk debug
this.level.timings.syncChunkLoad.stopTiming(); // Paper
@@ -759,7 +846,7 @@ index 585892f19bc0aea89889a358c0407f2975b9efe5..918fda0fbbafa39ce0f421dcaf10f8dc
} // Paper
ichunkaccess = (ChunkAccess) ((Either) completablefuture.join()).map((ichunkaccess1) -> {
return ichunkaccess1;
-@@ -711,10 +735,12 @@ public class ServerChunkCache extends ChunkSource {
+@@ -553,10 +581,12 @@ public class ServerChunkCache extends ChunkSource {
if (create && !currentlyUnloading) {
// CraftBukkit end
this.distanceManager.addTicket(TicketType.UNKNOWN, chunkcoordintpair, l, chunkcoordintpair);
@@ -772,7 +859,7 @@ index 585892f19bc0aea89889a358c0407f2975b9efe5..918fda0fbbafa39ce0f421dcaf10f8dc
this.runDistanceManagerUpdates();
playerchunk = this.getVisibleChunkIfPresent(k);
gameprofilerfiller.pop();
-@@ -724,7 +750,13 @@ public class ServerChunkCache extends ChunkSource {
+@@ -566,7 +596,13 @@ public class ServerChunkCache extends ChunkSource {
}
}
@@ -787,7 +874,7 @@ index 585892f19bc0aea89889a358c0407f2975b9efe5..918fda0fbbafa39ce0f421dcaf10f8dc
}
private boolean chunkAbsent(@Nullable ChunkHolder holder, int maxLevel) {
-@@ -776,6 +808,7 @@ public class ServerChunkCache extends ChunkSource {
+@@ -618,6 +654,7 @@ public class ServerChunkCache extends ChunkSource {
}
public boolean runDistanceManagerUpdates() {
@@ -796,10 +883,10 @@ index 585892f19bc0aea89889a358c0407f2975b9efe5..918fda0fbbafa39ce0f421dcaf10f8dc
boolean flag1 = this.chunkMap.promoteChunkMap();
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-index 0720b748ed42bbd2a12cc5de79224f609a5e29be..6f2b52165c1935511790a429792d3754251537c8 100644
+index 9ab4588e4e512176b881ad4c252e400ff6ea97bd..4adf2d503015cac85b12fbaae833b33eeeb44403 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-@@ -194,6 +194,7 @@ public class ServerPlayer extends Player {
+@@ -191,6 +191,7 @@ public class ServerPlayer extends Player {
private int lastRecordedArmor = Integer.MIN_VALUE;
private int lastRecordedLevel = Integer.MIN_VALUE;
private int lastRecordedExperience = Integer.MIN_VALUE;
@@ -807,9 +894,9 @@ index 0720b748ed42bbd2a12cc5de79224f609a5e29be..6f2b52165c1935511790a429792d3754
private float lastSentHealth = -1.0E8F;
private int lastSentFood = -99999999;
private boolean lastFoodSaturationZero = true;
-@@ -338,6 +339,21 @@ public class ServerPlayer extends Player {
+@@ -318,6 +319,21 @@ public class ServerPlayer extends Player {
+ this.bukkitPickUpLoot = true;
this.maxHealthCache = this.getMaxHealth();
- this.cachedSingleMobDistanceMap = new com.destroystokyo.paper.util.PooledHashSets.PooledObjectLinkedOpenHashSet<>(this); // Paper
}
+ // Paper start - Chunk priority
+ public BlockPos getPointInFront(double inFront) {
@@ -1099,7 +1186,7 @@ index f1128f0d4a9a0241ac6c9bc18dd13b431c616bb1..2b2b7851d5f68bcdb41d58bcc64740ba
protected Ticket(TicketType<T> type, int level, T argument) {
this.type = type;
diff --git a/src/main/java/net/minecraft/server/level/TicketType.java b/src/main/java/net/minecraft/server/level/TicketType.java
-index 8770fe0db46b01e8b608637df4f1a669a3f4cdde..3c1698ba0d3bc412ab957777d9b5211dbc555208 100644
+index 10fa6cec911950f72407ae7f45c8cf48caa9421a..478109526cff7ceb0565cea3b5e97b9a07fbf8d1 100644
--- a/src/main/java/net/minecraft/server/level/TicketType.java
+++ b/src/main/java/net/minecraft/server/level/TicketType.java
@@ -9,6 +9,8 @@ import net.minecraft.world.level.ChunkPos;
@@ -1112,33 +1199,22 @@ index 8770fe0db46b01e8b608637df4f1a669a3f4cdde..3c1698ba0d3bc412ab957777d9b5211d
private final String name;
private final Comparator<T> comparator;
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
-index 9819bb3c36e314103236832a133906957255ee7a..3ca3275f7f66410217b86ba8ca09d85ef64f3f83 100644
+index 5833cc3d5014dad82607afc4d643b6bed885be64..8e0f73dcef189442450b4518437fb3a1c34b9a47 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
-@@ -179,6 +179,7 @@ public abstract class PlayerList {
+@@ -177,6 +177,7 @@ public abstract class PlayerList {
}
public void placeNewPlayer(Connection connection, ServerPlayer player) {
+ player.isRealPlayer = true; // Paper - Chunk priority
- ServerPlayer prev = pendingPlayers.put(player.getUUID(), player);// Paper
- if (prev != null) {
- disconnectPendingPlayer(prev);
-@@ -294,8 +295,8 @@ public abstract class PlayerList {
- net.minecraft.server.level.ChunkMap playerChunkMap = worldserver1.getChunkSource().chunkMap;
- net.minecraft.server.level.DistanceManager distanceManager = playerChunkMap.distanceManager;
- distanceManager.addTicket(net.minecraft.server.level.TicketType.LOGIN, pos, 31, pos.toLong());
-- worldserver1.getChunkSource().runDistanceManagerUpdates();
-- worldserver1.getChunkSource().getChunkAtAsynchronously(chunkX, chunkZ, true, true).thenApply(chunk -> {
-+ worldserver1.getChunkSource().markAreaHighPriority(pos, 28, 3); // Paper - Chunk priority
-+ worldserver1.getChunkSource().getChunkAtAsynchronously(chunkX, chunkZ, true, false).thenApply(chunk -> { // Paper - Chunk priority
- net.minecraft.server.level.ChunkHolder updatingChunk = playerChunkMap.getUpdatingChunkIfPresent(pos.toLong());
- if (updatingChunk != null) {
- return updatingChunk.getEntityTickingChunkFuture();
+ GameProfile gameprofile = player.getGameProfile();
+ GameProfileCache usercache = this.server.getProfileCache();
+ Optional<GameProfile> optional = usercache.get(gameprofile.getId());
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
-index 258aa2ee24742d48be08940f147e1d998e667fb8..7e36e53d44b5efbd6498caecb717bec1dcbec96d 100644
+index 47a05aa42739f4cfce828c0de42b4f1da467093e..70c338f5bf605d2f51a21670634c716177cd6f97 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
-@@ -293,7 +293,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
+@@ -212,7 +212,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
private BlockPos blockPosition;
private ChunkPos chunkPosition;
private Vec3 deltaMovement;
@@ -1148,10 +1224,10 @@ index 258aa2ee24742d48be08940f147e1d998e667fb8..7e36e53d44b5efbd6498caecb717bec1
public float yRotO;
public float xRotO;
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
-index f8a3048fa80758d82f2e92d48bd3cd2c585ae6c2..2981ba61e347b8660082ff946521fc7f219d2c0d 100644
+index 58a245b2ca6e65d491694142ad04d38236b46434..893051059df51133a127b0870e27ab67461052fa 100644
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
-@@ -141,7 +141,7 @@ public class LevelChunk extends ChunkAccess {
+@@ -134,7 +134,7 @@ public class LevelChunk extends ChunkAccess {
return NEIGHBOUR_CACHE_RADIUS;
}
@@ -1160,7 +1236,7 @@ index f8a3048fa80758d82f2e92d48bd3cd2c585ae6c2..2981ba61e347b8660082ff946521fc7f
private long neighbourChunksLoadedBitset;
private final LevelChunk[] loadedNeighbourChunks = new LevelChunk[(NEIGHBOUR_CACHE_RADIUS * 2 + 1) * (NEIGHBOUR_CACHE_RADIUS * 2 + 1)];
-@@ -693,6 +693,7 @@ public class LevelChunk extends ChunkAccess {
+@@ -653,6 +653,7 @@ public class LevelChunk extends ChunkAccess {
// CraftBukkit start
public void loadCallback() {
@@ -1168,7 +1244,7 @@ index f8a3048fa80758d82f2e92d48bd3cd2c585ae6c2..2981ba61e347b8660082ff946521fc7f
// Paper start - neighbour cache
int chunkX = this.chunkPos.x;
int chunkZ = this.chunkPos.z;
-@@ -747,6 +748,7 @@ public class LevelChunk extends ChunkAccess {
+@@ -707,6 +708,7 @@ public class LevelChunk extends ChunkAccess {
}
public void unloadCallback() {
@@ -1176,41 +1252,3 @@ index f8a3048fa80758d82f2e92d48bd3cd2c585ae6c2..2981ba61e347b8660082ff946521fc7f
org.bukkit.Server server = this.level.getCraftServer();
org.bukkit.event.world.ChunkUnloadEvent unloadEvent = new org.bukkit.event.world.ChunkUnloadEvent(this.bukkitChunk, this.isUnsaved());
server.getPluginManager().callEvent(unloadEvent);
-diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-index b234ba968e82ddf1e8f7c84d3a17659e3beda2b3..af22fa8aa8ddef4d592564b14d0114cc6f903fca 100644
---- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-@@ -2077,6 +2077,12 @@ public class CraftWorld extends CraftRegionAccessor implements World {
- return future;
- }
-
-+ // Paper start - Chunk priority
-+ if (!urgent) {
-+ // If not urgent, at least use a slightly boosted priority
-+ world.getChunkSource().markHighPriority(new ChunkPos(x, z), 1);
-+ }
-+ // Paper end
- return this.world.getChunkSource().getChunkAtAsynchronously(x, z, gen, urgent).thenComposeAsync((either) -> {
- net.minecraft.world.level.chunk.LevelChunk chunk = (net.minecraft.world.level.chunk.LevelChunk) either.left().orElse(null);
- if (chunk != null) addTicket(x, z); // Paper
-diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
-index 0fda8c27c717bd030b826c5c7267b880f9d1f6b9..8db930d54ad97435e367aa670466d8a072ca0b23 100644
---- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
-+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
-@@ -1047,6 +1047,16 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
- throw new UnsupportedOperationException("Cannot set rotation of players. Consider teleporting instead.");
- }
-
-+ // Paper start - Chunk priority
-+ @Override
-+ public java.util.concurrent.CompletableFuture<Boolean> teleportAsync(Location loc, @javax.annotation.Nonnull PlayerTeleportEvent.TeleportCause cause) {
-+ ((CraftWorld)loc.getWorld()).getHandle().getChunkSource().markAreaHighPriority(
-+ new net.minecraft.world.level.ChunkPos(net.minecraft.util.Mth.floor(loc.getX()) >> 4,
-+ net.minecraft.util.Mth.floor(loc.getZ()) >> 4), 28, 3); // Load area high priority
-+ return super.teleportAsync(loc, cause);
-+ }
-+ // Paper end
-+
- @Override
- public boolean teleport(Location location, PlayerTeleportEvent.TeleportCause cause) {
- Preconditions.checkArgument(location != null, "location");
diff --git a/patches/server/0013-Add-command-line-option-to-load-extra-plugin-jars-no.patch b/patches/server/0021-Add-command-line-option-to-load-extra-plugin-jars-no.patch
index f7a089ab62..5bb64f964f 100644
--- a/patches/server/0013-Add-command-line-option-to-load-extra-plugin-jars-no.patch
+++ b/patches/server/0021-Add-command-line-option-to-load-extra-plugin-jars-no.patch
@@ -7,7 +7,7 @@ Subject: [PATCH] Add command line option to load extra plugin jars not in the
ex: java -jar paperclip.jar nogui -add-plugin=/path/to/plugin.jar -add-plugin=/path/to/another/plugin_jar.jar
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-index 5badb27d2060b0b13c54f8945848afbeb775fc6c..45c51529c9f94dfbd575ca94acd3c025bdb909e9 100644
+index eb5c7e15366ee5902d8c754a1e9daec50d26fb17..37fefdf0d96cd2b6e23b6e69ee5a8db16f0e51da 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -405,10 +405,15 @@ public final class CraftServer implements Server {
diff --git a/patches/server/0014-Configurable-cactus-bamboo-and-reed-growth-heights.patch b/patches/server/0022-Configurable-cactus-bamboo-and-reed-growth-heights.patch
index e794b359ef..e794b359ef 100644
--- a/patches/server/0014-Configurable-cactus-bamboo-and-reed-growth-heights.patch
+++ b/patches/server/0022-Configurable-cactus-bamboo-and-reed-growth-heights.patch
diff --git a/patches/server/0015-Configurable-baby-zombie-movement-speed.patch b/patches/server/0023-Configurable-baby-zombie-movement-speed.patch
index e0d10bc34b..e0d10bc34b 100644
--- a/patches/server/0015-Configurable-baby-zombie-movement-speed.patch
+++ b/patches/server/0023-Configurable-baby-zombie-movement-speed.patch
diff --git a/patches/server/0016-Configurable-fishing-time-ranges.patch b/patches/server/0024-Configurable-fishing-time-ranges.patch
index 71d66591ff..71d66591ff 100644
--- a/patches/server/0016-Configurable-fishing-time-ranges.patch
+++ b/patches/server/0024-Configurable-fishing-time-ranges.patch
diff --git a/patches/server/0017-Allow-nerfed-mobs-to-jump-and-take-water-damage.patch b/patches/server/0025-Allow-nerfed-mobs-to-jump-and-take-water-damage.patch
index c142430702..c142430702 100644
--- a/patches/server/0017-Allow-nerfed-mobs-to-jump-and-take-water-damage.patch
+++ b/patches/server/0025-Allow-nerfed-mobs-to-jump-and-take-water-damage.patch
diff --git a/patches/server/0018-Add-configurable-despawn-distances-for-living-entiti.patch b/patches/server/0026-Add-configurable-despawn-distances-for-living-entiti.patch
index 2724d12408..2724d12408 100644
--- a/patches/server/0018-Add-configurable-despawn-distances-for-living-entiti.patch
+++ b/patches/server/0026-Add-configurable-despawn-distances-for-living-entiti.patch
diff --git a/patches/server/0019-Allow-for-toggling-of-spawn-chunks.patch b/patches/server/0027-Allow-for-toggling-of-spawn-chunks.patch
index eb27f9892b..eb27f9892b 100644
--- a/patches/server/0019-Allow-for-toggling-of-spawn-chunks.patch
+++ b/patches/server/0027-Allow-for-toggling-of-spawn-chunks.patch
diff --git a/patches/server/0020-Drop-falling-block-and-tnt-entities-at-the-specified.patch b/patches/server/0028-Drop-falling-block-and-tnt-entities-at-the-specified.patch
index ed1b412de9..ed1b412de9 100644
--- a/patches/server/0020-Drop-falling-block-and-tnt-entities-at-the-specified.patch
+++ b/patches/server/0028-Drop-falling-block-and-tnt-entities-at-the-specified.patch
diff --git a/patches/server/0021-Show-Paper-in-client-crashes-server-lists-and-Mojang.patch b/patches/server/0029-Show-Paper-in-client-crashes-server-lists-and-Mojang.patch
index 15e19a0a94..40bf559133 100644
--- a/patches/server/0021-Show-Paper-in-client-crashes-server-lists-and-Mojang.patch
+++ b/patches/server/0029-Show-Paper-in-client-crashes-server-lists-and-Mojang.patch
@@ -6,7 +6,7 @@ Subject: [PATCH] Show 'Paper' in client crashes, server lists, and Mojang
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
-index 53be6189d3fa6a65a09996683913fbbf5133dcb7..e6acf596c2c62134e8d2e499d273aa326f792451 100644
+index d53fb6bba90936c1182b0687d014964cef81694f..645eaf7e6717486b583c49724c5891d5c270c38f 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -1432,7 +1432,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -63,7 +63,7 @@ index f64a690ed3173f78ed60b0262c0c868d97a803d5..ce104a63cd56f3343a0f58b0d7bcd47d
net.minecraft.server.Main.main(options);
} catch (Throwable t) {
diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/spigotmc/WatchdogThread.java
-index 335120afc88a8fc1543c2e6df516fd728e3ab032..d5863b0b06384b25eaa33572fa02649795463ed8 100644
+index 581cde7a74e00bee1ce69086132d5f871d206399..f8018902365e9115ae0132885a2546d115b24c36 100644
--- a/src/main/java/org/spigotmc/WatchdogThread.java
+++ b/src/main/java/org/spigotmc/WatchdogThread.java
@@ -19,7 +19,7 @@ public class WatchdogThread extends Thread
@@ -99,6 +99,6 @@ index 335120afc88a8fc1543c2e6df516fd728e3ab032..d5863b0b06384b25eaa33572fa026497
log.log( Level.SEVERE, "------------------------------" );
- log.log( Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Spigot!):" );
+ log.log( Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Paper!):" ); // Paper
+ com.destroystokyo.paper.io.chunk.ChunkTaskManager.dumpAllChunkLoadInfo(); // Paper
WatchdogThread.dumpThread( ManagementFactory.getThreadMXBean().getThreadInfo( MinecraftServer.getServer().serverThread.getId(), Integer.MAX_VALUE ), log );
log.log( Level.SEVERE, "------------------------------" );
- //
diff --git a/patches/server/0022-Implement-Paper-VersionChecker.patch b/patches/server/0030-Implement-Paper-VersionChecker.patch
index 127dce7216..ed72f43e9d 100644
--- a/patches/server/0022-Implement-Paper-VersionChecker.patch
+++ b/patches/server/0030-Implement-Paper-VersionChecker.patch
@@ -140,7 +140,7 @@ index 0000000000000000000000000000000000000000..351159bbdb0c8045f4983f54dee34430
+ }
+}
diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
-index 4f1945f854f4a022184ca4756b59d08b01693d6b..e6ffdbeb55eaeb8c2ea7c01a5206242f54756f2b 100644
+index e309a589e6ce76294187c906820a88367da25305..df814f6bd071cef89cd4275e11aadc8311abd0f4 100644
--- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
@@ -421,6 +421,11 @@ public final class CraftMagicNumbers implements UnsafeValues {
diff --git a/patches/server/0023-Add-version-history-to-version-command.patch b/patches/server/0031-Add-version-history-to-version-command.patch
index 3adbac0862..3adbac0862 100644
--- a/patches/server/0023-Add-version-history-to-version-command.patch
+++ b/patches/server/0031-Add-version-history-to-version-command.patch
diff --git a/patches/server/0024-Player-affects-spawning-API.patch b/patches/server/0032-Player-affects-spawning-API.patch
index 1684922404..749e5e7291 100644
--- a/patches/server/0024-Player-affects-spawning-API.patch
+++ b/patches/server/0032-Player-affects-spawning-API.patch
@@ -117,7 +117,7 @@ index 7c5918f84d2b8f9c778258b7e7d745105effb082..cfb286020b8ee87bad7edbda4cd0b999
for(Player player : this.players()) {
if (EntitySelector.NO_SPECTATORS.test(player) && EntitySelector.LIVING_ENTITY_STILL_ALIVE.test(player)) {
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
-index 7a95748f52ef064af3173deedc229ec0b5f65cac..dc4b1772bb447d84592f2c49bb04efee4dfd4494 100644
+index a2dd86fde8882c774ad44be3ca66f7c80bb77389..6132d91ba0f1390365f4661bcd7406000fa8a88d 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -1965,8 +1965,20 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
diff --git a/patches/server/0025-Further-improve-server-tick-loop.patch b/patches/server/0033-Further-improve-server-tick-loop.patch
index 20d5b674c1..f9f86a3271 100644
--- a/patches/server/0025-Further-improve-server-tick-loop.patch
+++ b/patches/server/0033-Further-improve-server-tick-loop.patch
@@ -12,7 +12,7 @@ Previous implementation did not calculate TPS correctly.
Switch to a realistic rolling average and factor in std deviation as an extra reporting variable
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
-index 97e2cbd5fa724ba5ba3f33ac1ce3da2e3e881eb8..0e982051f6c833fd5ff2ccbe098cb7a98bd0dc8a 100644
+index 645eaf7e6717486b583c49724c5891d5c270c38f..48a393f66013bf210ddac1e95496e1ec3727f314 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -270,7 +270,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -144,7 +144,7 @@ index 97e2cbd5fa724ba5ba3f33ac1ce3da2e3e881eb8..0e982051f6c833fd5ff2ccbe098cb7a9
this.startMetricsRecordingTick();
this.profiler.push("tick");
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-index df74d459809da72c55dd93c299dd2b414fb64dea..bd17e22c6cb3176da054bce3699c278b2354f193 100644
+index fc22de3e1bb4e01fc2c43ffd9ecd0a8cd6d40ba5..56efe95512c851b965f2295d5eac7bc0c67bdb1f 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -2409,6 +2409,17 @@ public final class CraftServer implements Server {
diff --git a/patches/server/0026-Only-refresh-abilities-if-needed.patch b/patches/server/0034-Only-refresh-abilities-if-needed.patch
index 872b218226..173e6b6366 100644
--- a/patches/server/0026-Only-refresh-abilities-if-needed.patch
+++ b/patches/server/0034-Only-refresh-abilities-if-needed.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] Only refresh abilities if needed
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
-index dc4b1772bb447d84592f2c49bb04efee4dfd4494..46abb31a5330662f46949466e01c404ba2922027 100644
+index 6132d91ba0f1390365f4661bcd7406000fa8a88d..68dddf4ded409f26a0c048d1b760f6ebb54da4ee 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -1634,12 +1634,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
diff --git a/patches/server/0027-Entity-Origin-API.patch b/patches/server/0035-Entity-Origin-API.patch
index 9c8f2f4d51..c0911d7e0e 100644
--- a/patches/server/0027-Entity-Origin-API.patch
+++ b/patches/server/0035-Entity-Origin-API.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Entity Origin API
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index 1d4d60fa861b5e819c59f06168a096688d06e656..b41f00840c87e27898d247ccf275185736883411 100644
+index 2f7646e2bcc9622d8579eec25b56615da5a84d06..f5ded21e15ca425d23af90f0e339a961c5600504 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
-@@ -2109,6 +2109,15 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -2185,6 +2185,15 @@ public class ServerLevel extends Level implements WorldGenLevel {
entity.updateDynamicGameEventListener(DynamicGameEventListener::add);
entity.valid = true; // CraftBukkit
@@ -25,7 +25,7 @@ index 1d4d60fa861b5e819c59f06168a096688d06e656..b41f00840c87e27898d247ccf2751857
public void onTrackingEnd(Entity entity) {
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
-index 47a05aa42739f4cfce828c0de42b4f1da467093e..a07aafad9f94b85a689568c1784727a8c5b0452b 100644
+index 70c338f5bf605d2f51a21670634c716177cd6f97..ef7320d69d058ea260e48dd1e0d4fc2d69aec1c2 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -304,7 +304,27 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
@@ -132,15 +132,14 @@ index 2d4a990da2402a6c24c03e8be7e518e33db99c8f..10f8b5ff56e4c1d8300835e045abdce7
@Nullable
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
-index 64687b0e04f619576f3e7f4fec0b559408048d38..f79f2867b62e25e9bf8e1102d12bcd07c913675b 100644
+index 7c9dcf62f85bb3ddffb4eadb3961d7b356c503f8..fba18e3c6903d4ed8233b4d32ed07bf08311ca27 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
-@@ -1166,4 +1166,21 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
- return this.spigot;
+@@ -1198,5 +1198,20 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
+
+ return ret;
}
- // Spigot end
+
-+ // Paper start
+ @Override
+ public Location getOrigin() {
+ Vector originVector = this.getHandle().getOriginVector();
@@ -155,5 +154,5 @@ index 64687b0e04f619576f3e7f4fec0b559408048d38..f79f2867b62e25e9bf8e1102d12bcd07
+ //noinspection ConstantConditions
+ return originVector.toLocation(world);
+ }
-+ // Paper end
+ // Paper end
}
diff --git a/patches/server/0028-Prevent-tile-entity-and-entity-crashes.patch b/patches/server/0036-Prevent-tile-entity-and-entity-crashes.patch
index 5337d1fa05..bd67245c87 100644
--- a/patches/server/0028-Prevent-tile-entity-and-entity-crashes.patch
+++ b/patches/server/0036-Prevent-tile-entity-and-entity-crashes.patch
@@ -44,10 +44,10 @@ index be08224c8107aab3e9a3645a20977dd14bfff782..c518704386f14cd033307dd976455c35
}
}
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
-index 58a245b2ca6e65d491694142ad04d38236b46434..a438025a2102fa911a6941cd9723c84743113dc7 100644
+index 893051059df51133a127b0870e27ab67461052fa..51b53bbed1dbd344d8646d4827e44ee7215524a9 100644
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
-@@ -1049,11 +1049,11 @@ public class LevelChunk extends ChunkAccess {
+@@ -1051,11 +1051,11 @@ public class LevelChunk extends ChunkAccess {
gameprofilerfiller.pop();
} catch (Throwable throwable) {
diff --git a/patches/server/0029-Configurable-top-of-nether-void-damage.patch b/patches/server/0037-Configurable-top-of-nether-void-damage.patch
index c35c0ea546..d5007abffd 100644
--- a/patches/server/0029-Configurable-top-of-nether-void-damage.patch
+++ b/patches/server/0037-Configurable-top-of-nether-void-damage.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] Configurable top of nether void damage
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
-index a07aafad9f94b85a689568c1784727a8c5b0452b..45aca8dde5b6f1a3aef907b1a74809e7f4aa66e4 100644
+index ef7320d69d058ea260e48dd1e0d4fc2d69aec1c2..a761c5b3551c7a87b8d04b03f5640805007fbcd3 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -653,7 +653,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
diff --git a/patches/server/0030-Check-online-mode-before-converting-and-renaming-pla.patch b/patches/server/0038-Check-online-mode-before-converting-and-renaming-pla.patch
index 64f713e616..64f713e616 100644
--- a/patches/server/0030-Check-online-mode-before-converting-and-renaming-pla.patch
+++ b/patches/server/0038-Check-online-mode-before-converting-and-renaming-pla.patch
diff --git a/patches/server/0031-Always-tick-falling-blocks.patch b/patches/server/0039-Always-tick-falling-blocks.patch
index c52ac50408..c52ac50408 100644
--- a/patches/server/0031-Always-tick-falling-blocks.patch
+++ b/patches/server/0039-Always-tick-falling-blocks.patch
diff --git a/patches/server/0032-Configurable-end-credits.patch b/patches/server/0040-Configurable-end-credits.patch
index e4e3d7fd81..f36351998f 100644
--- a/patches/server/0032-Configurable-end-credits.patch
+++ b/patches/server/0040-Configurable-end-credits.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Configurable end credits
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-index 58aea845e8ce6e46e52fc3bdfa9c64153c32a750..5ff3bf1c436fd69e6129e59c205f626df9d61e8d 100644
+index 4adf2d503015cac85b12fbaae833b33eeeb44403..13bb12a2d1260b1c20ce3c8755906c2227f29f86 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-@@ -988,6 +988,7 @@ public class ServerPlayer extends Player {
+@@ -1004,6 +1004,7 @@ public class ServerPlayer extends Player {
this.unRide();
this.getLevel().removePlayerImmediately(this, Entity.RemovalReason.CHANGED_DIMENSION);
if (!this.wonGame) {
diff --git a/patches/server/0033-Fix-lag-from-explosions-processing-dead-entities.patch b/patches/server/0041-Fix-lag-from-explosions-processing-dead-entities.patch
index 3a8886ecac..3a8886ecac 100644
--- a/patches/server/0033-Fix-lag-from-explosions-processing-dead-entities.patch
+++ b/patches/server/0041-Fix-lag-from-explosions-processing-dead-entities.patch
diff --git a/patches/server/0034-Optimize-explosions.patch b/patches/server/0042-Optimize-explosions.patch
index f52c29e3cc..f644570779 100644
--- a/patches/server/0034-Optimize-explosions.patch
+++ b/patches/server/0042-Optimize-explosions.patch
@@ -10,7 +10,7 @@ This patch adds a per-tick cache that is used for storing and retrieving
an entity's exposure during an explosion.
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
-index 494ee4d6de47d10b2f9e4be393f1fe2603a72167..40ea9d30c5d9a0936ba495adea4d96775bce2e06 100644
+index 48a393f66013bf210ddac1e95496e1ec3727f314..a65d86f7b48bf1fbc2186804a8c05921363c7272 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -1395,6 +1395,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
diff --git a/patches/server/0035-Disable-explosion-knockback.patch b/patches/server/0043-Disable-explosion-knockback.patch
index 6c4346e6f2..61079fbbba 100644
--- a/patches/server/0035-Disable-explosion-knockback.patch
+++ b/patches/server/0043-Disable-explosion-knockback.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] Disable explosion knockback
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
-index 8221ec36a6453aea8a2249fde93ebc8fbd9d7e22..c1c0757852c4925bcd1debe79a3946c972c4be70 100644
+index e2d93d7a9c421f896e98e6dd6b318f9a30cab3b4..0d61cb2b7af48bbc60b04be6a4767ccba2b29ffb 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -1399,6 +1399,7 @@ public abstract class LivingEntity extends Entity {
diff --git a/patches/server/0036-Disable-thunder.patch b/patches/server/0044-Disable-thunder.patch
index 935ec83b16..cdf69c62c6 100644
--- a/patches/server/0036-Disable-thunder.patch
+++ b/patches/server/0044-Disable-thunder.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Disable thunder
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index b41f00840c87e27898d247ccf275185736883411..bd8a24a5a4c6640be570678af688470c47d92500 100644
+index f5ded21e15ca425d23af90f0e339a961c5600504..e44b2662da3af5967801a21aaee0b30ef939e2ac 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
-@@ -583,7 +583,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -659,7 +659,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
gameprofilerfiller.push("thunder");
BlockPos blockposition;
diff --git a/patches/server/0037-Disable-ice-and-snow.patch b/patches/server/0045-Disable-ice-and-snow.patch
index 917d38a2b1..25327d73d7 100644
--- a/patches/server/0037-Disable-ice-and-snow.patch
+++ b/patches/server/0045-Disable-ice-and-snow.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Disable ice and snow
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index bd8a24a5a4c6640be570678af688470c47d92500..5d693946111a73e25fcbff2475a2f47a44066fbf 100644
+index e44b2662da3af5967801a21aaee0b30ef939e2ac..3a41a346e886918160eccaee57118747e33f6cc1 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
-@@ -607,7 +607,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -683,7 +683,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
}
gameprofilerfiller.popPush("iceandsnow");
diff --git a/patches/server/0038-Configurable-mob-spawner-tick-rate.patch b/patches/server/0046-Configurable-mob-spawner-tick-rate.patch
index b33478a7a0..b33478a7a0 100644
--- a/patches/server/0038-Configurable-mob-spawner-tick-rate.patch
+++ b/patches/server/0046-Configurable-mob-spawner-tick-rate.patch
diff --git a/patches/server/0039-Implement-PlayerLocaleChangeEvent.patch b/patches/server/0047-Implement-PlayerLocaleChangeEvent.patch
index 41fbaec734..af210058a9 100644
--- a/patches/server/0039-Implement-PlayerLocaleChangeEvent.patch
+++ b/patches/server/0047-Implement-PlayerLocaleChangeEvent.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Implement PlayerLocaleChangeEvent
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-index 16c4df6bd5b84b5e7a820ba14f2b2ee80b5b401c..48ffa3fce91ad98d9e4c099aacf6c0a84b2093e4 100644
+index 13bb12a2d1260b1c20ce3c8755906c2227f29f86..db7e2207612b56b0869a947edd03a6d3f9209e22 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-@@ -1754,7 +1754,7 @@ public class ServerPlayer extends Player {
+@@ -1770,7 +1770,7 @@ public class ServerPlayer extends Player {
return s;
}
@@ -17,7 +17,7 @@ index 16c4df6bd5b84b5e7a820ba14f2b2ee80b5b401c..48ffa3fce91ad98d9e4c099aacf6c0a8
public java.util.Locale adventure$locale = java.util.Locale.US; // Paper
public void updateOptions(ServerboundClientInformationPacket packet) {
// CraftBukkit start
-@@ -1762,9 +1762,10 @@ public class ServerPlayer extends Player {
+@@ -1778,9 +1778,10 @@ public class ServerPlayer extends Player {
PlayerChangedMainHandEvent event = new PlayerChangedMainHandEvent(this.getBukkitEntity(), getMainArm() == HumanoidArm.LEFT ? MainHand.LEFT : MainHand.RIGHT);
this.server.server.getPluginManager().callEvent(event);
}
@@ -30,7 +30,7 @@ index 16c4df6bd5b84b5e7a820ba14f2b2ee80b5b401c..48ffa3fce91ad98d9e4c099aacf6c0a8
this.locale = packet.language;
// Paper start
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
-index 6d2609222afa3cd5f99118281c20281f8c2f792f..9bcffda912e3cc7322043e705dddfe052f4b1273 100644
+index 68dddf4ded409f26a0c048d1b760f6ebb54da4ee..7f0dd0b718a08c850f07f3e0b0a0cf680f1bb2eb 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -1965,8 +1965,10 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
diff --git a/patches/server/0040-Per-Player-View-Distance-API-placeholders.patch b/patches/server/0048-Per-Player-View-Distance-API-placeholders.patch
index ccdb2bf31b..9f490acf67 100644
--- a/patches/server/0040-Per-Player-View-Distance-API-placeholders.patch
+++ b/patches/server/0048-Per-Player-View-Distance-API-placeholders.patch
@@ -7,10 +7,10 @@ I hope to look at this more in-depth soon. It appears doable.
However this should not block the update.
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-index 48ffa3fce91ad98d9e4c099aacf6c0a84b2093e4..28d8ba2f421245ab6707ea982e76d543916a1e51 100644
+index db7e2207612b56b0869a947edd03a6d3f9209e22..981e60c7bf2eee52e84f9894ff689631388a7715 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-@@ -2237,4 +2237,6 @@ public class ServerPlayer extends Player {
+@@ -2253,4 +2253,6 @@ public class ServerPlayer extends Player {
return (CraftPlayer) super.getBukkitEntity();
}
// CraftBukkit end
@@ -18,7 +18,7 @@ index 48ffa3fce91ad98d9e4c099aacf6c0a84b2093e4..28d8ba2f421245ab6707ea982e76d543
+ public final int getViewDistance() { return this.getLevel().getChunkSource().chunkMap.viewDistance - 1; } // Paper - placeholder
}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-index cf7762e76a2d35acdfc12627e9750fbec766d555..40d6b00fb40db167c6c80b6a3f79eb82d08cdfb9 100644
+index 9a6820b10e4164cc38d269853b5c2a49175cb890..0ed46cdd443ac42a7d57ee59f6f04fd9e9259c16 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -1913,6 +1913,37 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@@ -60,7 +60,7 @@ index cf7762e76a2d35acdfc12627e9750fbec766d555..40d6b00fb40db167c6c80b6a3f79eb82
// Spigot start
private final org.bukkit.World.Spigot spigot = new org.bukkit.World.Spigot()
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
-index 9bcffda912e3cc7322043e705dddfe052f4b1273..62a4ae1ee2a0784787b6f45bff6393630e1d4219 100644
+index 7f0dd0b718a08c850f07f3e0b0a0cf680f1bb2eb..82a640887a75c360539c1787dbbb32750f6b1379 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -402,6 +402,46 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
diff --git a/patches/server/0041-Add-BeaconEffectEvent.patch b/patches/server/0049-Add-BeaconEffectEvent.patch
index 4c04a07cd0..4c04a07cd0 100644
--- a/patches/server/0041-Add-BeaconEffectEvent.patch
+++ b/patches/server/0049-Add-BeaconEffectEvent.patch
diff --git a/patches/server/0042-Configurable-container-update-tick-rate.patch b/patches/server/0050-Configurable-container-update-tick-rate.patch
index 8c964f14a8..21abeaf37e 100644
--- a/patches/server/0042-Configurable-container-update-tick-rate.patch
+++ b/patches/server/0050-Configurable-container-update-tick-rate.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Configurable container update tick rate
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-index b6a19cd2cfd8acfac6dde77033bbb82ef20586d0..b117a98dea77755bee33f8a141f8df16b587beeb 100644
+index 981e60c7bf2eee52e84f9894ff689631388a7715..4d8dfe375f5b3b9e5cfc12a6af0b87ae78f9b764 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-@@ -228,6 +228,7 @@ public class ServerPlayer extends Player {
+@@ -229,6 +229,7 @@ public class ServerPlayer extends Player {
private int containerCounter;
public int latency;
public boolean wonGame;
@@ -16,7 +16,7 @@ index b6a19cd2cfd8acfac6dde77033bbb82ef20586d0..b117a98dea77755bee33f8a141f8df16
// CraftBukkit start
public String displayName;
-@@ -600,7 +601,12 @@ public class ServerPlayer extends Player {
+@@ -616,7 +617,12 @@ public class ServerPlayer extends Player {
--this.invulnerableTime;
}
diff --git a/patches/server/0043-Use-UserCache-for-player-heads.patch b/patches/server/0051-Use-UserCache-for-player-heads.patch
index 2381324116..2381324116 100644
--- a/patches/server/0043-Use-UserCache-for-player-heads.patch
+++ b/patches/server/0051-Use-UserCache-for-player-heads.patch
diff --git a/patches/server/0044-Disable-spigot-tick-limiters.patch b/patches/server/0052-Disable-spigot-tick-limiters.patch
index b750d86014..b750d86014 100644
--- a/patches/server/0044-Disable-spigot-tick-limiters.patch
+++ b/patches/server/0052-Disable-spigot-tick-limiters.patch
diff --git a/patches/server/0045-Add-PlayerInitialSpawnEvent.patch b/patches/server/0053-Add-PlayerInitialSpawnEvent.patch
index 271cf7952a..4242de963c 100644
--- a/patches/server/0045-Add-PlayerInitialSpawnEvent.patch
+++ b/patches/server/0053-Add-PlayerInitialSpawnEvent.patch
@@ -9,10 +9,10 @@ This is a duplicate API from spigot, so use our duplicate subclass and
improve setPosition to use raw
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
-index bffd4efcbe50609b134b2bf498dc393e7ef70850..28c136fe37afeda1b43523a17a46a115f1dbf3f3 100644
+index 8e0f73dcef189442450b4518437fb3a1c34b9a47..c003a1e8b4c2b2331abc4536352abdec20fef42e 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
-@@ -222,7 +222,7 @@ public abstract class PlayerList {
+@@ -223,7 +223,7 @@ public abstract class PlayerList {
// Spigot start - spawn location event
Player spawnPlayer = player.getBukkitEntity();
@@ -21,7 +21,7 @@ index bffd4efcbe50609b134b2bf498dc393e7ef70850..28c136fe37afeda1b43523a17a46a115
this.cserver.getPluginManager().callEvent(ev);
Location loc = ev.getSpawnLocation();
-@@ -230,7 +230,10 @@ public abstract class PlayerList {
+@@ -231,7 +231,10 @@ public abstract class PlayerList {
player.spawnIn(worldserver1);
player.gameMode.setLevel((ServerLevel) player.level);
diff --git a/patches/server/0046-Configurable-Disabling-Cat-Chest-Detection.patch b/patches/server/0054-Configurable-Disabling-Cat-Chest-Detection.patch
index 85180f4352..85180f4352 100644
--- a/patches/server/0046-Configurable-Disabling-Cat-Chest-Detection.patch
+++ b/patches/server/0054-Configurable-Disabling-Cat-Chest-Detection.patch
diff --git a/patches/server/0047-Ensure-commands-are-not-ran-async.patch b/patches/server/0055-Ensure-commands-are-not-ran-async.patch
index 5e7762a60d..3b81d4e6a7 100644
--- a/patches/server/0047-Ensure-commands-are-not-ran-async.patch
+++ b/patches/server/0055-Ensure-commands-are-not-ran-async.patch
@@ -21,10 +21,10 @@ character.
Co-authored-by: Jake Potrebic <[email protected]>
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-index cdc24defe649644ceade1c6cfcfe20c29ca936c1..4fe65f979e8c3c15aea2211035745a71aef0feeb 100644
+index 5072d4dc1f7f77c61e3cc72c1101cb95f6596ce7..451dd594a2acc6fbc7112b9ecfa737c942f10a3c 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-@@ -2026,7 +2026,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
+@@ -2033,7 +2033,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
return true;
}
@@ -33,7 +33,7 @@ index cdc24defe649644ceade1c6cfcfe20c29ca936c1..4fe65f979e8c3c15aea2211035745a71
for (int i = 0; i < message.length(); ++i) {
if (!SharedConstants.isAllowedChatCharacter(message.charAt(i))) {
return true;
-@@ -2043,7 +2043,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
+@@ -2050,7 +2050,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
}
OutgoingPlayerChatMessage outgoing = OutgoingPlayerChatMessage.create(original);
@@ -42,7 +42,7 @@ index cdc24defe649644ceade1c6cfcfe20c29ca936c1..4fe65f979e8c3c15aea2211035745a71
this.handleCommand(s);
} else if (this.player.getChatVisibility() == ChatVisiblity.SYSTEM) {
// Do nothing, this is coming from a plugin
-@@ -2146,7 +2146,29 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
+@@ -2153,7 +2153,29 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
}
}
diff --git a/patches/server/0048-All-chunks-are-slime-spawn-chunks-toggle.patch b/patches/server/0056-All-chunks-are-slime-spawn-chunks-toggle.patch
index c510a84432..c510a84432 100644
--- a/patches/server/0048-All-chunks-are-slime-spawn-chunks-toggle.patch
+++ b/patches/server/0056-All-chunks-are-slime-spawn-chunks-toggle.patch
diff --git a/patches/server/0049-Expose-server-CommandMap.patch b/patches/server/0057-Expose-server-CommandMap.patch
index 1eb15fa1c0..4270ea1e72 100644
--- a/patches/server/0049-Expose-server-CommandMap.patch
+++ b/patches/server/0057-Expose-server-CommandMap.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] Expose server CommandMap
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-index b61a98f2711c8aeca65e6e782c07ace05c56fbe8..4c0f321128271f77a54b1ed814033cdd8a712350 100644
+index 1c6577bbbc005131661cbb4667cff6494b8fe5e4..fd3ccc1726cd73e9f5be3f936115e2431c77183c 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -1983,6 +1983,7 @@ public final class CraftServer implements Server {
diff --git a/patches/server/0050-Be-a-bit-more-informative-in-maxHealth-exception.patch b/patches/server/0058-Be-a-bit-more-informative-in-maxHealth-exception.patch
index edd16859a7..edd16859a7 100644
--- a/patches/server/0050-Be-a-bit-more-informative-in-maxHealth-exception.patch
+++ b/patches/server/0058-Be-a-bit-more-informative-in-maxHealth-exception.patch
diff --git a/patches/server/0051-Ensure-inv-drag-is-in-bounds.patch b/patches/server/0059-Ensure-inv-drag-is-in-bounds.patch
index da2779ebd5..da2779ebd5 100644
--- a/patches/server/0051-Ensure-inv-drag-is-in-bounds.patch
+++ b/patches/server/0059-Ensure-inv-drag-is-in-bounds.patch
diff --git a/patches/server/0052-Player-Tab-List-and-Title-APIs.patch b/patches/server/0060-Player-Tab-List-and-Title-APIs.patch
index 09f96b3601..9d0c41ec61 100644
--- a/patches/server/0052-Player-Tab-List-and-Title-APIs.patch
+++ b/patches/server/0060-Player-Tab-List-and-Title-APIs.patch
@@ -63,7 +63,7 @@ index bd808eb312ade7122973a47f4b96505829511da5..bf0f9cab7c66c089f35b851e799ba4a4
// Paper end
buf.writeComponent(this.text);
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
-index b73b202a3c68ba559b65245186a97025bda25134..383168bc9af2174cbe6a0c914d0dbbc8b9d3d156 100644
+index 2666e55d72fd7731a2bde42d690762a2747dac90..f4f704ec29cb9eb2f4de2b77261a54169bb40a93 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -1,5 +1,6 @@
diff --git a/patches/server/0053-Add-configurable-portal-search-radius.patch b/patches/server/0061-Add-configurable-portal-search-radius.patch
index e209c92ee2..911f221d1d 100644
--- a/patches/server/0053-Add-configurable-portal-search-radius.patch
+++ b/patches/server/0061-Add-configurable-portal-search-radius.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] Add configurable portal search radius
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
-index 45aca8dde5b6f1a3aef907b1a74809e7f4aa66e4..d95f2f0757a339917ff8061ae3cf169bbed054bf 100644
+index a761c5b3551c7a87b8d04b03f5640805007fbcd3..3bf89827afc515ffae0f79532b38c5f31ba014f6 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -2937,7 +2937,13 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
diff --git a/patches/server/0054-Add-velocity-warnings.patch b/patches/server/0062-Add-velocity-warnings.patch
index 649ff7887d..1f75e318ba 100644
--- a/patches/server/0054-Add-velocity-warnings.patch
+++ b/patches/server/0062-Add-velocity-warnings.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] Add velocity warnings
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-index 4c0f321128271f77a54b1ed814033cdd8a712350..fe4bf2bdd43d4d85c62d3939305dbecc1ae01eb9 100644
+index fd3ccc1726cd73e9f5be3f936115e2431c77183c..c1c86dc95d610bb391191317fa0c0e4c8e41d198 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -280,6 +280,7 @@ public final class CraftServer implements Server {
@@ -17,7 +17,7 @@ index 4c0f321128271f77a54b1ed814033cdd8a712350..fe4bf2bdd43d4d85c62d3939305dbecc
static {
ConfigurationSerialization.registerClass(CraftOfflinePlayer.class);
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
-index f79f2867b62e25e9bf8e1102d12bcd07c913675b..e1ae00c1639b4ff18e061d86b006ff733494bb00 100644
+index fba18e3c6903d4ed8233b4d32ed07bf08311ca27..8b4f1ef248d0b13927cbf634a0e2a97eb93c8ae4 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
@@ -450,10 +450,40 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
@@ -62,7 +62,7 @@ index f79f2867b62e25e9bf8e1102d12bcd07c913675b..e1ae00c1639b4ff18e061d86b006ff73
public double getHeight() {
return this.getHandle().getBbHeight();
diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/spigotmc/WatchdogThread.java
-index d5863b0b06384b25eaa33572fa02649795463ed8..2693cc933d746e40d8a47d96c6cb6799f0a2472f 100644
+index f8018902365e9115ae0132885a2546d115b24c36..600c012b2bf119ddd6760b0401a2c6a22453609e 100644
--- a/src/main/java/org/spigotmc/WatchdogThread.java
+++ b/src/main/java/org/spigotmc/WatchdogThread.java
@@ -80,7 +80,19 @@ public class WatchdogThread extends Thread
@@ -85,4 +85,4 @@ index d5863b0b06384b25eaa33572fa02649795463ed8..2693cc933d746e40d8a47d96c6cb6799
+ // Paper end
log.log( Level.SEVERE, "------------------------------" );
log.log( Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Paper!):" ); // Paper
- WatchdogThread.dumpThread( ManagementFactory.getThreadMXBean().getThreadInfo( MinecraftServer.getServer().serverThread.getId(), Integer.MAX_VALUE ), log );
+ com.destroystokyo.paper.io.chunk.ChunkTaskManager.dumpAllChunkLoadInfo(); // Paper
diff --git a/patches/server/0055-Configurable-inter-world-teleportation-safety.patch b/patches/server/0063-Configurable-inter-world-teleportation-safety.patch
index 5f2a39c0d7..4863fd9b13 100644
--- a/patches/server/0055-Configurable-inter-world-teleportation-safety.patch
+++ b/patches/server/0063-Configurable-inter-world-teleportation-safety.patch
@@ -16,7 +16,7 @@ The wanted destination was on top of the emerald block however the player ended
This only is the case if the player is teleporting between worlds.
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
-index 97307be401ca8a5207aa7b96a6f7961f9fc76786..3794d05b17378ebf517199adbbfd54a395ef6b37 100644
+index f4f704ec29cb9eb2f4de2b77261a54169bb40a93..d91f69639724aeeb4264f86cf8f76edc22567649 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -1050,7 +1050,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
diff --git a/patches/server/0056-Add-exception-reporting-event.patch b/patches/server/0064-Add-exception-reporting-event.patch
index 3875f2110a..fb76a4b5df 100644
--- a/patches/server/0056-Add-exception-reporting-event.patch
+++ b/patches/server/0064-Add-exception-reporting-event.patch
@@ -49,10 +49,10 @@ index 0000000000000000000000000000000000000000..f699ce18ca044f813e194ef2786b7ea8
+ }
+}
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
-index ca1e483819bffc948fab10f88563084aa75d1484..1c73599e37e9b830ff0ab9bcc9edc7b63daa6ca1 100644
+index 46bfaf04867d913c1782d851de101d913376c63a..4af8cee31d20e5dcec510439795e7e90fc668128 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
-@@ -999,6 +999,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -1187,6 +1187,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
return true;
} catch (Exception exception) {
ChunkMap.LOGGER.error("Failed to save chunk {},{}", new Object[]{chunkcoordintpair.x, chunkcoordintpair.z, exception});
@@ -143,7 +143,7 @@ index b37e04a0c466dacf52e74a4d4fb0885511c2abc1..878fc7f57178bff0e42fd01434f0aaa2
}
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
-index a438025a2102fa911a6941cd9723c84743113dc7..2704a05766d42b0277fa6308820b88371db00ace 100644
+index 51b53bbed1dbd344d8646d4827e44ee7215524a9..a4e121365717036dfc27eec86549d6dbac1ffc1a 100644
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
@@ -1,6 +1,7 @@
@@ -175,7 +175,7 @@ index a438025a2102fa911a6941cd9723c84743113dc7..2704a05766d42b0277fa6308820b8837
// CraftBukkit end
}
}
-@@ -1052,6 +1059,7 @@ public class LevelChunk extends ChunkAccess {
+@@ -1054,6 +1061,7 @@ public class LevelChunk extends ChunkAccess {
// Paper start - Prevent tile entity and entity crashes
final String msg = String.format("BlockEntity threw exception at %s:%s,%s,%s", LevelChunk.this.getLevel().getWorld().getName(), this.getPos().getX(), this.getPos().getY(), this.getPos().getZ());
net.minecraft.server.MinecraftServer.LOGGER.error(msg, throwable);
@@ -184,10 +184,10 @@ index a438025a2102fa911a6941cd9723c84743113dc7..2704a05766d42b0277fa6308820b8837
// Paper end
// Spigot start
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java
-index d51bafd2f5a763b8a49c835ab74a7cf60caa1ab6..fbf5f01a9a7968194fc85589ca7f9fa328da4881 100644
+index 7412da51c2eae70f17f4883f7223303d570c8402..8adebb8408cc22ae7e9e89721645e5dd27a41cd8 100644
--- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java
-@@ -274,6 +274,7 @@ public class RegionFile implements AutoCloseable {
+@@ -275,6 +275,7 @@ public class RegionFile implements AutoCloseable {
return true;
}
} catch (IOException ioexception) {
@@ -195,7 +195,7 @@ index d51bafd2f5a763b8a49c835ab74a7cf60caa1ab6..fbf5f01a9a7968194fc85589ca7f9fa3
return false;
}
}
-@@ -355,6 +356,7 @@ public class RegionFile implements AutoCloseable {
+@@ -356,6 +357,7 @@ public class RegionFile implements AutoCloseable {
((java.nio.Buffer) bytebuffer).position(5); // CraftBukkit - decompile error
filechannel.write(bytebuffer);
} catch (Throwable throwable) {
diff --git a/patches/server/0057-Don-t-nest-if-we-don-t-need-to-when-cerealising-text.patch b/patches/server/0065-Don-t-nest-if-we-don-t-need-to-when-cerealising-text.patch
index 3d801ecb90..3d801ecb90 100644
--- a/patches/server/0057-Don-t-nest-if-we-don-t-need-to-when-cerealising-text.patch
+++ b/patches/server/0065-Don-t-nest-if-we-don-t-need-to-when-cerealising-text.patch
diff --git a/patches/server/0058-Disable-Scoreboards-for-non-players-by-default.patch b/patches/server/0066-Disable-Scoreboards-for-non-players-by-default.patch
index 65ba2b1f02..f95a3237bf 100644
--- a/patches/server/0058-Disable-Scoreboards-for-non-players-by-default.patch
+++ b/patches/server/0066-Disable-Scoreboards-for-non-players-by-default.patch
@@ -11,7 +11,7 @@ So avoid looking up scoreboards and short circuit to the "not on a team"
logic which is most likely to be true.
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
-index d95f2f0757a339917ff8061ae3cf169bbed054bf..0f50355ea57101e71df6990c1e19c7b927f5c306 100644
+index 3bf89827afc515ffae0f79532b38c5f31ba014f6..4218d5aa5b4ba77d304b91c6c6cd9fa9cdaaa532 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -2575,6 +2575,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
@@ -23,7 +23,7 @@ index d95f2f0757a339917ff8061ae3cf169bbed054bf..0f50355ea57101e71df6990c1e19c7b9
}
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
-index c1c0757852c4925bcd1debe79a3946c972c4be70..d6e5f48fca5a965fc073ecca29ba5e24a4cd52f2 100644
+index 0d61cb2b7af48bbc60b04be6a4767ccba2b29ffb..3023e714961d1b565d9e8659e07ccc4dab729f2f 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -823,6 +823,7 @@ public abstract class LivingEntity extends Entity {
diff --git a/patches/server/0059-Add-methods-for-working-with-arrows-stuck-in-living-.patch b/patches/server/0067-Add-methods-for-working-with-arrows-stuck-in-living-.patch
index b73f1a823f..b73f1a823f 100644
--- a/patches/server/0059-Add-methods-for-working-with-arrows-stuck-in-living-.patch
+++ b/patches/server/0067-Add-methods-for-working-with-arrows-stuck-in-living-.patch
diff --git a/patches/server/0060-Chunk-Save-Reattempt.patch b/patches/server/0068-Chunk-Save-Reattempt.patch
index 82a269b220..a10ae30efd 100644
--- a/patches/server/0060-Chunk-Save-Reattempt.patch
+++ b/patches/server/0068-Chunk-Save-Reattempt.patch
@@ -6,10 +6,10 @@ Subject: [PATCH] Chunk Save Reattempt
We commonly have "Stream Closed" errors on chunk saving, so this code should re-try to save the chunk in the event of failure and hopefully prevent rollbacks.
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java
-index fbf5f01a9a7968194fc85589ca7f9fa328da4881..2d74ab966a1291895b6248a67a31fe4802b3773f 100644
+index 8adebb8408cc22ae7e9e89721645e5dd27a41cd8..038e2177182c94baa4af24f9111cf155ec342dfe 100644
--- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java
-@@ -274,7 +274,7 @@ public class RegionFile implements AutoCloseable {
+@@ -275,7 +275,7 @@ public class RegionFile implements AutoCloseable {
return true;
}
} catch (IOException ioexception) {
@@ -19,33 +19,33 @@ index fbf5f01a9a7968194fc85589ca7f9fa328da4881..2d74ab966a1291895b6248a67a31fe48
}
}
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
-index 8ba1c073387fa21a20bd42a873ec3cc314eae64e..eaf22cec54b512e0f57606f50627d5fe9b39bd5c 100644
+index 6fa0bc18ab05b9fb05521f46c5dadb695f1ec05b..4210c43104de01200b149e13ffab09dea37c5caf 100644
--- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
-@@ -131,6 +131,7 @@ public class RegionFileStorage implements AutoCloseable {
-
+@@ -163,6 +163,7 @@ public class RegionFileStorage implements AutoCloseable {
protected void write(ChunkPos pos, @Nullable CompoundTag nbt) throws IOException {
- RegionFile regionfile = this.getRegionFile(pos, false); // CraftBukkit
+ RegionFile regionfile = this.getRegionFile(pos, false, true); // CraftBukkit // Paper
+ try { // Paper
+ int attempts = 0; Exception laste = null; while (attempts++ < 5) { try { // Paper
if (nbt == null) {
regionfile.clear(pos);
-@@ -156,6 +157,18 @@ public class RegionFileStorage implements AutoCloseable {
+@@ -187,7 +188,18 @@ public class RegionFileStorage implements AutoCloseable {
+ dataoutputstream.close();
}
}
-
-+ // Paper start
-+ return;
++ // Paper start
++ return;
+ } catch (Exception ex) {
+ laste = ex;
+ }
+ }
-+
+
+ if (laste != null) {
+ com.destroystokyo.paper.exception.ServerInternalException.reportInternalException(laste);
-+ net.minecraft.server.MinecraftServer.LOGGER.error("Failed to save chunk", laste);
++ net.minecraft.server.MinecraftServer.LOGGER.error("Failed to save chunk " + pos, laste);
+ }
+ // Paper end
- }
-
- public void close() throws IOException {
+ } finally { // Paper start
+ regionfile.fileLock.unlock();
+ } // Paper end
diff --git a/patches/server/0061-Complete-resource-pack-API.patch b/patches/server/0069-Complete-resource-pack-API.patch
index d92f972605..de2eef11b5 100644
--- a/patches/server/0061-Complete-resource-pack-API.patch
+++ b/patches/server/0069-Complete-resource-pack-API.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Complete resource pack API
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-index 4fe65f979e8c3c15aea2211035745a71aef0feeb..bcd95c61ba98604552c3269e974e27b88658f38e 100644
+index 451dd594a2acc6fbc7112b9ecfa737c942f10a3c..e4f1b7fca8046df11f7e212c316385f82ce45322 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-@@ -1756,8 +1756,11 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
+@@ -1763,8 +1763,11 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
ServerGamePacketListenerImpl.LOGGER.info("Disconnecting {} due to resource pack rejection", this.player.getName());
this.disconnect(Component.translatable("multiplayer.requiredTexturePrompt.disconnect"));
}
diff --git a/patches/server/0062-Default-loading-permissions.yml-before-plugins.patch b/patches/server/0070-Default-loading-permissions.yml-before-plugins.patch
index 2492bada58..6b823b51be 100644
--- a/patches/server/0062-Default-loading-permissions.yml-before-plugins.patch
+++ b/patches/server/0070-Default-loading-permissions.yml-before-plugins.patch
@@ -16,7 +16,7 @@ modify that. Under the previous logic, plugins were unable (cleanly) override pe
A config option has been added for those who depend on the previous behavior, but I don't expect that.
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-index fe4bf2bdd43d4d85c62d3939305dbecc1ae01eb9..63eabacf2743d14bb02147869e51491e392b96bf 100644
+index c1c86dc95d610bb391191317fa0c0e4c8e41d198..2df58a9f40843abca02125d5f094129a8a75caf5 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -462,6 +462,7 @@ public final class CraftServer implements Server {
diff --git a/patches/server/0063-Allow-Reloading-of-Custom-Permissions.patch b/patches/server/0071-Allow-Reloading-of-Custom-Permissions.patch
index 88c1b9b95a..fa49c037a8 100644
--- a/patches/server/0063-Allow-Reloading-of-Custom-Permissions.patch
+++ b/patches/server/0071-Allow-Reloading-of-Custom-Permissions.patch
@@ -6,7 +6,7 @@ Subject: [PATCH] Allow Reloading of Custom Permissions
https://github.com/PaperMC/Paper/issues/49
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-index 63eabacf2743d14bb02147869e51491e392b96bf..858707ce778fad5bbdcc31e61de57dbfed2f94b4 100644
+index 2df58a9f40843abca02125d5f094129a8a75caf5..d4016a8890fff0805bacab3e5a556e7316c9ab25 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -2537,5 +2537,23 @@ public final class CraftServer implements Server {
diff --git a/patches/server/0064-Remove-Metadata-on-reload.patch b/patches/server/0072-Remove-Metadata-on-reload.patch
index dce360d5ec..7e8fa9271c 100644
--- a/patches/server/0064-Remove-Metadata-on-reload.patch
+++ b/patches/server/0072-Remove-Metadata-on-reload.patch
@@ -7,7 +7,7 @@ Metadata is not meant to persist reload as things break badly with non primitive
This will remove metadata on reload so it does not crash everything if a plugin uses it.
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-index 858707ce778fad5bbdcc31e61de57dbfed2f94b4..460d95ece9a9ba053a50d5a1cf69ac3bc85131a3 100644
+index d4016a8890fff0805bacab3e5a556e7316c9ab25..9a3b5b491256537d54c5fd0ac1646b3eb726187d 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -950,8 +950,16 @@ public final class CraftServer implements Server {
diff --git a/patches/server/0065-Handle-Item-Meta-Inconsistencies.patch b/patches/server/0073-Handle-Item-Meta-Inconsistencies.patch
index cd2cb25067..cd2cb25067 100644
--- a/patches/server/0065-Handle-Item-Meta-Inconsistencies.patch
+++ b/patches/server/0073-Handle-Item-Meta-Inconsistencies.patch
diff --git a/patches/server/0066-Configurable-Non-Player-Arrow-Despawn-Rate.patch b/patches/server/0074-Configurable-Non-Player-Arrow-Despawn-Rate.patch
index 9544e6114a..9544e6114a 100644
--- a/patches/server/0066-Configurable-Non-Player-Arrow-Despawn-Rate.patch
+++ b/patches/server/0074-Configurable-Non-Player-Arrow-Despawn-Rate.patch
diff --git a/patches/server/0067-Add-World-Util-Methods.patch b/patches/server/0075-Add-World-Util-Methods.patch
index 20d322962d..72c0c64816 100644
--- a/patches/server/0067-Add-World-Util-Methods.patch
+++ b/patches/server/0075-Add-World-Util-Methods.patch
@@ -6,7 +6,7 @@ Subject: [PATCH] Add World Util Methods
Methods that can be used for other patches to help improve logic.
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index 5d693946111a73e25fcbff2475a2f47a44066fbf..8f1c2d8e6cd0500f7e51d134cb5ea549752a1184 100644
+index 3a41a346e886918160eccaee57118747e33f6cc1..7e663cb0a214d59baaa6d3da75a8e2fca05cc56d 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -216,7 +216,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
diff --git a/patches/server/0068-Custom-replacement-for-eaten-items.patch b/patches/server/0076-Custom-replacement-for-eaten-items.patch
index fc5200a6d4..fc5200a6d4 100644
--- a/patches/server/0068-Custom-replacement-for-eaten-items.patch
+++ b/patches/server/0076-Custom-replacement-for-eaten-items.patch
diff --git a/patches/server/0069-handle-NaN-health-absorb-values-and-repair-bad-data.patch b/patches/server/0077-handle-NaN-health-absorb-values-and-repair-bad-data.patch
index edc3918f65..9e4b4b1cbb 100644
--- a/patches/server/0069-handle-NaN-health-absorb-values-and-repair-bad-data.patch
+++ b/patches/server/0077-handle-NaN-health-absorb-values-and-repair-bad-data.patch
@@ -44,7 +44,7 @@ index 1dcf41a4105c05c3182afa8585dee20723d2c136..54e7fa7a483e15c440f562559601292c
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
-index b85ca8bded5157adad810b9a50ca0fe377597c93..edd750b20a3367a1fb00ed5df593102730a8f26a 100644
+index 6ae934c6c7c50dd38ff2e762fddfe650e97aa4ae..da91150f7462c2743d7394b148ddb52e9af8b797 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -1932,6 +1932,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
diff --git a/patches/server/0070-Use-a-Shared-Random-for-Entities.patch b/patches/server/0078-Use-a-Shared-Random-for-Entities.patch
index a843fc1916..fa08041dbb 100644
--- a/patches/server/0070-Use-a-Shared-Random-for-Entities.patch
+++ b/patches/server/0078-Use-a-Shared-Random-for-Entities.patch
@@ -6,7 +6,7 @@ Subject: [PATCH] Use a Shared Random for Entities
Reduces memory usage and provides ensures more randomness, Especially since a lot of garbage entity objects get created.
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
-index 0f50355ea57101e71df6990c1e19c7b927f5c306..829dc369891c0d120da6ed00ab981c6fd204596d 100644
+index 4218d5aa5b4ba77d304b91c6c6cd9fa9cdaaa532..72915f876d456a28ea3609e46861412052065f37 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -159,6 +159,79 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
diff --git a/patches/server/0071-Configurable-spawn-chances-for-skeleton-horses.patch b/patches/server/0079-Configurable-spawn-chances-for-skeleton-horses.patch
index 95175f6fe6..0af7b6e1ad 100644
--- a/patches/server/0071-Configurable-spawn-chances-for-skeleton-horses.patch
+++ b/patches/server/0079-Configurable-spawn-chances-for-skeleton-horses.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Configurable spawn chances for skeleton horses
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index 8f1c2d8e6cd0500f7e51d134cb5ea549752a1184..22e0612183be9e419d52ac2274dc728900433249 100644
+index 7e663cb0a214d59baaa6d3da75a8e2fca05cc56d..44600f8915f04f0baf3f877dff43d23e1b8ad93a 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
-@@ -587,7 +587,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -663,7 +663,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
blockposition = this.findLightningTargetAround(this.getBlockRandomPos(j, 0, k, 15));
if (this.isRainingAt(blockposition)) {
DifficultyInstance difficultydamagescaler = this.getCurrentDifficultyAt(blockposition);
diff --git a/patches/server/0072-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch b/patches/server/0080-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch
index a013493ee6..4c1319763c 100644
--- a/patches/server/0072-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch
+++ b/patches/server/0080-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch
@@ -88,7 +88,7 @@ index 3dff0f7c3ccd04a67b2153e402d801de2341e520..7b320357973202423c29743d922b72dc
@Override
public FluidState getFluidState(BlockPos pos) {
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
-index 2704a05766d42b0277fa6308820b88371db00ace..a508b7c6dbf9f7acdca77c219d7dd2492cd7c6b8 100644
+index a4e121365717036dfc27eec86549d6dbac1ffc1a..4c4f44457d2066ea37cf48e37a282d8896649bc5 100644
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
@@ -296,12 +296,29 @@ public class LevelChunk extends ChunkAccess {
diff --git a/patches/server/0073-Only-process-BlockPhysicsEvent-if-a-plugin-has-a-lis.patch b/patches/server/0081-Only-process-BlockPhysicsEvent-if-a-plugin-has-a-lis.patch
index 5109b67c42..ed5e601ed1 100644
--- a/patches/server/0073-Only-process-BlockPhysicsEvent-if-a-plugin-has-a-lis.patch
+++ b/patches/server/0081-Only-process-BlockPhysicsEvent-if-a-plugin-has-a-lis.patch
@@ -6,7 +6,7 @@ Subject: [PATCH] Only process BlockPhysicsEvent if a plugin has a listener
Saves on some object allocation and processing when no plugin listens to this
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
-index 40ea9d30c5d9a0936ba495adea4d96775bce2e06..00424041950529973eaf33f4d312dbd1038ae675 100644
+index a65d86f7b48bf1fbc2186804a8c05921363c7272..4fc75c6086c7f41414b73b901c7a90f06267a089 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -1356,6 +1356,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -18,7 +18,7 @@ index 40ea9d30c5d9a0936ba495adea4d96775bce2e06..00424041950529973eaf33f4d312dbd1
this.profiler.push(() -> {
return worldserver + " " + worldserver.dimension().location();
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index 22e0612183be9e419d52ac2274dc728900433249..bd60bb4a1fa7f3c38c651f72bc58dffcd5736b43 100644
+index 44600f8915f04f0baf3f877dff43d23e1b8ad93a..79c22c0eb5adf6e08f7978272b8482fe53c4a45a 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -215,6 +215,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
diff --git a/patches/server/0074-Entity-AddTo-RemoveFrom-World-Events.patch b/patches/server/0082-Entity-AddTo-RemoveFrom-World-Events.patch
index 1bb60c8efa..bc343d006f 100644
--- a/patches/server/0074-Entity-AddTo-RemoveFrom-World-Events.patch
+++ b/patches/server/0082-Entity-AddTo-RemoveFrom-World-Events.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Entity AddTo/RemoveFrom World Events
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index bd60bb4a1fa7f3c38c651f72bc58dffcd5736b43..c94fc95adfce7ec4ab3d881f1667f2f54ae38393 100644
+index 79c22c0eb5adf6e08f7978272b8482fe53c4a45a..14f55837c8614633b9a6edf7d35af465fbf8aa17 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
-@@ -2119,6 +2119,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -2195,6 +2195,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
entity.setOrigin(entity.getOriginVector().toLocation(getWorld()));
}
// Paper end
@@ -16,7 +16,7 @@ index bd60bb4a1fa7f3c38c651f72bc58dffcd5736b43..c94fc95adfce7ec4ab3d881f1667f2f5
}
public void onTrackingEnd(Entity entity) {
-@@ -2194,6 +2195,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -2270,6 +2271,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
}
}
// CraftBukkit end
diff --git a/patches/server/0075-Configurable-Chunk-Inhabited-Time.patch b/patches/server/0083-Configurable-Chunk-Inhabited-Time.patch
index 3dc363ab29..44d87ae0db 100644
--- a/patches/server/0075-Configurable-Chunk-Inhabited-Time.patch
+++ b/patches/server/0083-Configurable-Chunk-Inhabited-Time.patch
@@ -11,7 +11,7 @@ For people who want all chunks to be treated equally, you can chose a fixed valu
This allows to fine-tune vanilla gameplay.
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
-index a508b7c6dbf9f7acdca77c219d7dd2492cd7c6b8..e9fae214f60fe682087d41cfaa55a1b25e5f4331 100644
+index 4c4f44457d2066ea37cf48e37a282d8896649bc5..e63086aba2512051fe1321f6e7e72b40276f5dde 100644
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
@@ -281,6 +281,13 @@ public class LevelChunk extends ChunkAccess {
diff --git a/patches/server/0076-EntityPathfindEvent.patch b/patches/server/0084-EntityPathfindEvent.patch
index b076482d21..b076482d21 100644
--- a/patches/server/0076-EntityPathfindEvent.patch
+++ b/patches/server/0084-EntityPathfindEvent.patch
diff --git a/patches/server/0077-Sanitise-RegionFileCache-and-make-configurable.patch b/patches/server/0085-Sanitise-RegionFileCache-and-make-configurable.patch
index 071a254a0c..c1c284728b 100644
--- a/patches/server/0077-Sanitise-RegionFileCache-and-make-configurable.patch
+++ b/patches/server/0085-Sanitise-RegionFileCache-and-make-configurable.patch
@@ -11,11 +11,11 @@ The implementation uses a LinkedHashMap as an LRU cache (modified from HashMap).
The maximum size of the RegionFileCache is also made configurable.
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
-index eaf22cec54b512e0f57606f50627d5fe9b39bd5c..5a35e5040726a981ae91f018f05b91c178a54ba0 100644
+index 4210c43104de01200b149e13ffab09dea37c5caf..b790bb574546fef1969584529e49dbcf1403e198 100644
--- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
-@@ -36,7 +36,7 @@ public class RegionFileStorage implements AutoCloseable {
- if (regionfile != null) {
+@@ -57,7 +57,7 @@ public class RegionFileStorage implements AutoCloseable {
+ // Paper end
return regionfile;
} else {
- if (this.regionCache.size() >= 256) {
diff --git a/patches/server/0078-Do-not-load-chunks-for-Pathfinding.patch b/patches/server/0086-Do-not-load-chunks-for-Pathfinding.patch
index f2b3dffd68..f2b3dffd68 100644
--- a/patches/server/0078-Do-not-load-chunks-for-Pathfinding.patch
+++ b/patches/server/0086-Do-not-load-chunks-for-Pathfinding.patch
diff --git a/patches/server/0079-Add-PlayerUseUnknownEntityEvent.patch b/patches/server/0087-Add-PlayerUseUnknownEntityEvent.patch
index 63947ccb44..b9bcde6187 100644
--- a/patches/server/0079-Add-PlayerUseUnknownEntityEvent.patch
+++ b/patches/server/0087-Add-PlayerUseUnknownEntityEvent.patch
@@ -20,10 +20,10 @@ index 8834ed411a7db86b4d2b88183a1315317107d719..c45b5ab6776f3ac79f856c3a6467c510
static final ServerboundInteractPacket.Action ATTACK_ACTION = new ServerboundInteractPacket.Action() {
@Override
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-index bcd95c61ba98604552c3269e974e27b88658f38e..33237c6a9f8885abdd5379d17be2b71ad7c2204e 100644
+index e4f1b7fca8046df11f7e212c316385f82ce45322..1161ed7ba2a32a42fb092f3f76af0bba958c44ae 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-@@ -2635,8 +2635,37 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
+@@ -2642,8 +2642,37 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
});
}
}
diff --git a/patches/server/0080-Configurable-Grass-Spread-Tick-Rate.patch b/patches/server/0088-Configurable-Grass-Spread-Tick-Rate.patch
index 50a9c78703..50a9c78703 100644
--- a/patches/server/0080-Configurable-Grass-Spread-Tick-Rate.patch
+++ b/patches/server/0088-Configurable-Grass-Spread-Tick-Rate.patch
diff --git a/patches/server/0081-Fix-Cancelling-BlockPlaceEvent-triggering-physics.patch b/patches/server/0089-Fix-Cancelling-BlockPlaceEvent-triggering-physics.patch
index d56c30920d..02bb35bb40 100644
--- a/patches/server/0081-Fix-Cancelling-BlockPlaceEvent-triggering-physics.patch
+++ b/patches/server/0089-Fix-Cancelling-BlockPlaceEvent-triggering-physics.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Fix Cancelling BlockPlaceEvent triggering physics
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index c94fc95adfce7ec4ab3d881f1667f2f54ae38393..14e618db89745942893f82d57f5383fcca6c41e9 100644
+index 14f55837c8614633b9a6edf7d35af465fbf8aa17..af3eab8bb09ca86a38724f38417b03a55b6bb06c 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
-@@ -1365,6 +1365,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -1441,6 +1441,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
@Override
public void updateNeighborsAt(BlockPos pos, Block sourceBlock) {
diff --git a/patches/server/0082-Optimize-DataBits.patch b/patches/server/0090-Optimize-DataBits.patch
index 8686b1aff9..8686b1aff9 100644
--- a/patches/server/0082-Optimize-DataBits.patch
+++ b/patches/server/0090-Optimize-DataBits.patch
diff --git a/patches/server/0083-Option-to-use-vanilla-per-world-scoreboard-coloring-.patch b/patches/server/0091-Option-to-use-vanilla-per-world-scoreboard-coloring-.patch
index 7ef4294205..7ef4294205 100644
--- a/patches/server/0083-Option-to-use-vanilla-per-world-scoreboard-coloring-.patch
+++ b/patches/server/0091-Option-to-use-vanilla-per-world-scoreboard-coloring-.patch
diff --git a/patches/server/0084-Configurable-Player-Collision.patch b/patches/server/0092-Configurable-Player-Collision.patch
index 6a8a20af72..e72b7dc458 100644
--- a/patches/server/0084-Configurable-Player-Collision.patch
+++ b/patches/server/0092-Configurable-Player-Collision.patch
@@ -18,7 +18,7 @@ index 1294b38262505b0d54089e428df9b363219de1f0..ee37ec0de1ca969144824427ae42b0c8
buf.writeComponent(this.playerPrefix);
buf.writeComponent(this.playerSuffix);
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
-index 00424041950529973eaf33f4d312dbd1038ae675..0dffb6e8d6f4edfb4dfaa6b24e81d72356446ebc 100644
+index 4fc75c6086c7f41414b73b901c7a90f06267a089..23e9a4ba6b108aa7a7fb8e0c4a765986380eefbd 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -580,6 +580,20 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -43,7 +43,7 @@ index 00424041950529973eaf33f4d312dbd1038ae675..0dffb6e8d6f4edfb4dfaa6b24e81d723
this.server.getPluginManager().callEvent(new ServerLoadEvent(ServerLoadEvent.LoadType.STARTUP));
this.connection.acceptConnections();
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
-index b2a47e33a0503c79d10f8979391f7dfa4b619b28..b4f29bed0332489ccae54cfb7a7f90e4df89743f 100644
+index c003a1e8b4c2b2331abc4536352abdec20fef42e..a474241c66a532791d9734ab9a9f6529f5414169 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -94,6 +94,7 @@ import net.minecraft.world.level.storage.PlayerDataStorage;
@@ -62,7 +62,7 @@ index b2a47e33a0503c79d10f8979391f7dfa4b619b28..b4f29bed0332489ccae54cfb7a7f90e4
public PlayerList(MinecraftServer server, RegistryAccess.Frozen registryManager, PlayerDataStorage saveHandler, int maxPlayers) {
this.cserver = server.server = new CraftServer((DedicatedServer) server, this);
-@@ -390,6 +392,13 @@ public abstract class PlayerList {
+@@ -391,6 +393,13 @@ public abstract class PlayerList {
player.initInventoryMenu();
// CraftBukkit - Moved from above, added world
@@ -76,7 +76,7 @@ index b2a47e33a0503c79d10f8979391f7dfa4b619b28..b4f29bed0332489ccae54cfb7a7f90e4
PlayerList.LOGGER.info("{}[{}] logged in with entity id {} at ([{}]{}, {}, {})", player.getName().getString(), s1, player.getId(), worldserver1.serverLevelData.getLevelName(), player.getX(), player.getY(), player.getZ());
}
-@@ -509,6 +518,16 @@ public abstract class PlayerList {
+@@ -510,6 +519,16 @@ public abstract class PlayerList {
entityplayer.doTick(); // SPIGOT-924
// CraftBukkit end
@@ -93,7 +93,7 @@ index b2a47e33a0503c79d10f8979391f7dfa4b619b28..b4f29bed0332489ccae54cfb7a7f90e4
this.save(entityplayer);
if (entityplayer.isPassenger()) {
Entity entity = entityplayer.getRootVehicle();
-@@ -1137,6 +1156,13 @@ public abstract class PlayerList {
+@@ -1138,6 +1157,13 @@ public abstract class PlayerList {
}
// CraftBukkit end
diff --git a/patches/server/0085-Add-handshake-event-to-allow-plugins-to-handle-clien.patch b/patches/server/0093-Add-handshake-event-to-allow-plugins-to-handle-clien.patch
index 0f1b5b5544..0f1b5b5544 100644
--- a/patches/server/0085-Add-handshake-event-to-allow-plugins-to-handle-clien.patch
+++ b/patches/server/0093-Add-handshake-event-to-allow-plugins-to-handle-clien.patch
diff --git a/patches/server/0086-Configurable-RCON-IP-address.patch b/patches/server/0094-Configurable-RCON-IP-address.patch
index fa6341c5b8..fa6341c5b8 100644
--- a/patches/server/0086-Configurable-RCON-IP-address.patch
+++ b/patches/server/0094-Configurable-RCON-IP-address.patch
diff --git a/patches/server/0087-EntityRegainHealthEvent-isFastRegen-API.patch b/patches/server/0095-EntityRegainHealthEvent-isFastRegen-API.patch
index 06e6c5137b..06e6c5137b 100644
--- a/patches/server/0087-EntityRegainHealthEvent-isFastRegen-API.patch
+++ b/patches/server/0095-EntityRegainHealthEvent-isFastRegen-API.patch
diff --git a/patches/server/0088-Add-ability-to-configure-frosted_ice-properties.patch b/patches/server/0096-Add-ability-to-configure-frosted_ice-properties.patch
index 8e938c31ad..8e938c31ad 100644
--- a/patches/server/0088-Add-ability-to-configure-frosted_ice-properties.patch
+++ b/patches/server/0096-Add-ability-to-configure-frosted_ice-properties.patch
diff --git a/patches/server/0089-remove-null-possibility-for-getServer-singleton.patch b/patches/server/0097-remove-null-possibility-for-getServer-singleton.patch
index d043453096..81ef84ab00 100644
--- a/patches/server/0089-remove-null-possibility-for-getServer-singleton.patch
+++ b/patches/server/0097-remove-null-possibility-for-getServer-singleton.patch
@@ -6,7 +6,7 @@ Subject: [PATCH] remove null possibility for getServer singleton
to stop IDE complaining about potential NPE
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
-index a6c184d450e08737e0053f7526de2ab6e20c454b..c667f8b115ad77ca3d3f908d69915d60d950ffe5 100644
+index 23e9a4ba6b108aa7a7fb8e0c4a765986380eefbd..1dc2234b8218699d82a56e23d9390bee6cc7937b 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -181,6 +181,7 @@ import co.aikar.timings.MinecraftTimings; // Paper
diff --git a/patches/server/0090-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch b/patches/server/0098-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch
index 4928c59f9a..2e33bb81a2 100644
--- a/patches/server/0090-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch
+++ b/patches/server/0098-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch
@@ -13,10 +13,10 @@ custom renderers are in use, defaulting to the much simpler Vanilla system.
Additionally, numerous issues to player position tracking on maps has been fixed.
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index 14e618db89745942893f82d57f5383fcca6c41e9..652c909eaa9e76c29427b7220adf9fe4947c2e84 100644
+index af3eab8bb09ca86a38724f38417b03a55b6bb06c..4a6c03f421d81b694ca8670994c9322d4425922b 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
-@@ -2140,6 +2140,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -2216,6 +2216,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
{
if ( iter.next().player == entity )
{
diff --git a/patches/server/0091-LootTable-API-Replenishable-Lootables-Feature.patch b/patches/server/0099-LootTable-API-Replenishable-Lootables-Feature.patch
index 3c8564f12a..3893dcb7f0 100644
--- a/patches/server/0091-LootTable-API-Replenishable-Lootables-Feature.patch
+++ b/patches/server/0099-LootTable-API-Replenishable-Lootables-Feature.patch
@@ -485,7 +485,7 @@ index 0000000000000000000000000000000000000000..3377b86c337d0234bbb9b0349e4034a7
+ }
+}
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
-index 829dc369891c0d120da6ed00ab981c6fd204596d..0fe534337ea72b338583039644f1f2b5be76d385 100644
+index 72915f876d456a28ea3609e46861412052065f37..32d230dc6968306dd6e322ffd6a820380e3c88b1 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -232,6 +232,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
diff --git a/patches/server/0092-Don-t-save-empty-scoreboard-teams-to-scoreboard.dat.patch b/patches/server/0100-Don-t-save-empty-scoreboard-teams-to-scoreboard.dat.patch
index c233fb2657..c233fb2657 100644
--- a/patches/server/0092-Don-t-save-empty-scoreboard-teams-to-scoreboard.dat.patch
+++ b/patches/server/0100-Don-t-save-empty-scoreboard-teams-to-scoreboard.dat.patch
diff --git a/patches/server/0093-System-property-for-disabling-watchdoge.patch b/patches/server/0101-System-property-for-disabling-watchdoge.patch
index 8d880e6928..62f6387e73 100644
--- a/patches/server/0093-System-property-for-disabling-watchdoge.patch
+++ b/patches/server/0101-System-property-for-disabling-watchdoge.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] System property for disabling watchdoge
diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/spigotmc/WatchdogThread.java
-index 2693cc933d746e40d8a47d96c6cb6799f0a2472f..6e1fa4f0616ccfd258acd1b4f5b08fc0ad4c9529 100644
+index 600c012b2bf119ddd6760b0401a2c6a22453609e..bd515ddc88f71a31531418c43725e438de100fcd 100644
--- a/src/main/java/org/spigotmc/WatchdogThread.java
+++ b/src/main/java/org/spigotmc/WatchdogThread.java
@@ -61,7 +61,7 @@ public class WatchdogThread extends Thread
diff --git a/patches/server/0094-Async-GameProfileCache-saving.patch b/patches/server/0102-Async-GameProfileCache-saving.patch
index d640169a04..12dab86f58 100644
--- a/patches/server/0094-Async-GameProfileCache-saving.patch
+++ b/patches/server/0102-Async-GameProfileCache-saving.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] Async GameProfileCache saving
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
-index b3834c86eb79400c8cef60daa03c90a66b03b688..f3f528cc7f07da69c45e4290de098c0443c7a952 100644
+index 1dc2234b8218699d82a56e23d9390bee6cc7937b..da790861a3689195446040e8e7d2f898eee3068e 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -945,7 +945,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -16,7 +16,7 @@ index b3834c86eb79400c8cef60daa03c90a66b03b688..f3f528cc7f07da69c45e4290de098c04
+ this.getProfileCache().save(false); // Paper
}
// Spigot end
-
+ com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.close(true, true); // Paper
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
index d70d97c65d5bdb47a17a226d65bad8ba1421b11b..5b2980866ae3cd78f1852b0ad396ff1967ddfc16 100644
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
diff --git a/patches/server/0095-Optional-TNT-doesn-t-move-in-water.patch b/patches/server/0103-Optional-TNT-doesn-t-move-in-water.patch
index 3cb11be6b8..3cb11be6b8 100644
--- a/patches/server/0095-Optional-TNT-doesn-t-move-in-water.patch
+++ b/patches/server/0103-Optional-TNT-doesn-t-move-in-water.patch
diff --git a/patches/server/0096-Faster-redstone-torch-rapid-clock-removal.patch b/patches/server/0104-Faster-redstone-torch-rapid-clock-removal.patch
index bb9244b467..bb9244b467 100644
--- a/patches/server/0096-Faster-redstone-torch-rapid-clock-removal.patch
+++ b/patches/server/0104-Faster-redstone-torch-rapid-clock-removal.patch
diff --git a/patches/server/0097-Add-server-name-parameter.patch b/patches/server/0105-Add-server-name-parameter.patch
index ae657c8fce..4feb170ed5 100644
--- a/patches/server/0097-Add-server-name-parameter.patch
+++ b/patches/server/0105-Add-server-name-parameter.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] Add server-name parameter
diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java
-index 8962c8669802dabd6a7bc5b6e506f5d921becea2..d7766aaaaa9fd69aae162046cbd2410f8bfeb14c 100644
+index ce104a63cd56f3343a0f58b0d7bcd47d885beb7f..04e7295ab4ec7e417ebb272f5f1b26721dfbb476 100644
--- a/src/main/java/org/bukkit/craftbukkit/Main.java
+++ b/src/main/java/org/bukkit/craftbukkit/Main.java
@@ -154,6 +154,14 @@ public class Main {
diff --git a/patches/server/0098-Only-send-Dragon-Wither-Death-sounds-to-same-world.patch b/patches/server/0106-Only-send-Dragon-Wither-Death-sounds-to-same-world.patch
index 1cfb68f251..1cfb68f251 100644
--- a/patches/server/0098-Only-send-Dragon-Wither-Death-sounds-to-same-world.patch
+++ b/patches/server/0106-Only-send-Dragon-Wither-Death-sounds-to-same-world.patch
diff --git a/patches/server/0099-Fix-Old-Sign-Conversion.patch b/patches/server/0107-Fix-Old-Sign-Conversion.patch
index d223b39ccf..d223b39ccf 100644
--- a/patches/server/0099-Fix-Old-Sign-Conversion.patch
+++ b/patches/server/0107-Fix-Old-Sign-Conversion.patch
diff --git a/patches/server/0100-Avoid-blocking-on-Network-Manager-creation.patch b/patches/server/0108-Avoid-blocking-on-Network-Manager-creation.patch
index 4c0273aeef..4c0273aeef 100644
--- a/patches/server/0100-Avoid-blocking-on-Network-Manager-creation.patch
+++ b/patches/server/0108-Avoid-blocking-on-Network-Manager-creation.patch
diff --git a/patches/server/0101-Don-t-lookup-game-profiles-that-have-no-UUID-and-no-.patch b/patches/server/0109-Don-t-lookup-game-profiles-that-have-no-UUID-and-no-.patch
index e542d272fa..e542d272fa 100644
--- a/patches/server/0101-Don-t-lookup-game-profiles-that-have-no-UUID-and-no-.patch
+++ b/patches/server/0109-Don-t-lookup-game-profiles-that-have-no-UUID-and-no-.patch
diff --git a/patches/server/0102-Add-setting-for-proxy-online-mode-status.patch b/patches/server/0110-Add-setting-for-proxy-online-mode-status.patch
index 97a2f69145..3cca2594aa 100644
--- a/patches/server/0102-Add-setting-for-proxy-online-mode-status.patch
+++ b/patches/server/0110-Add-setting-for-proxy-online-mode-status.patch
@@ -43,7 +43,7 @@ index da98f074ccd5a40c635824112c97fd174c393cb1..6599f874d9f97e9ef4862039ecad7277
} else {
String[] astring1 = astring;
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-index 460d95ece9a9ba053a50d5a1cf69ac3bc85131a3..cc4bd65d8f9f3824e77e4509a8f0dbda5c2f01a6 100644
+index 9a3b5b491256537d54c5fd0ac1646b3eb726187d..6e28fd088ff19bcd2206f2d8decf72184d109baf 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -1706,7 +1706,7 @@ public final class CraftServer implements Server {
diff --git a/patches/server/0103-Optimise-BlockState-s-hashCode-equals.patch b/patches/server/0111-Optimise-BlockState-s-hashCode-equals.patch
index 53db895e2e..53db895e2e 100644
--- a/patches/server/0103-Optimise-BlockState-s-hashCode-equals.patch
+++ b/patches/server/0111-Optimise-BlockState-s-hashCode-equals.patch
diff --git a/patches/server/0104-Configurable-packet-in-spam-threshold.patch b/patches/server/0112-Configurable-packet-in-spam-threshold.patch
index 9934046175..ff39852896 100644
--- a/patches/server/0104-Configurable-packet-in-spam-threshold.patch
+++ b/patches/server/0112-Configurable-packet-in-spam-threshold.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Configurable packet in spam threshold
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-index 33237c6a9f8885abdd5379d17be2b71ad7c2204e..cea1e100fb0cc7fe4768d1b5de518019fd69b2f8 100644
+index 1161ed7ba2a32a42fb092f3f76af0bba958c44ae..b62171dc10d0c3a1dfefbb7f083a333899a1f1bb 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-@@ -1604,13 +1604,14 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
+@@ -1611,13 +1611,14 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
// Spigot start - limit place/interactions
private int limitedPackets;
private long lastLimitedPacket = -1;
diff --git a/patches/server/0105-Configurable-flying-kick-messages.patch b/patches/server/0113-Configurable-flying-kick-messages.patch
index 3daa3bd62f..2f466ef787 100644
--- a/patches/server/0105-Configurable-flying-kick-messages.patch
+++ b/patches/server/0113-Configurable-flying-kick-messages.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] Configurable flying kick messages
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-index cea1e100fb0cc7fe4768d1b5de518019fd69b2f8..952ad96c310b8d1285e1dd07ec224d5005d5c8cc 100644
+index b62171dc10d0c3a1dfefbb7f083a333899a1f1bb..c8f9223f750ec0825c45288d52df149f94748d5d 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -358,7 +358,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
diff --git a/patches/server/0106-Add-EntityZapEvent.patch b/patches/server/0114-Add-EntityZapEvent.patch
index 545c1bc427..545c1bc427 100644
--- a/patches/server/0106-Add-EntityZapEvent.patch
+++ b/patches/server/0114-Add-EntityZapEvent.patch
diff --git a/patches/server/0107-Filter-bad-data-from-ArmorStand-and-SpawnEgg-items.patch b/patches/server/0115-Filter-bad-data-from-ArmorStand-and-SpawnEgg-items.patch
index 9fc8ffaeaf..9fc8ffaeaf 100644
--- a/patches/server/0107-Filter-bad-data-from-ArmorStand-and-SpawnEgg-items.patch
+++ b/patches/server/0115-Filter-bad-data-from-ArmorStand-and-SpawnEgg-items.patch
diff --git a/patches/server/0108-Cache-user-authenticator-threads.patch b/patches/server/0116-Cache-user-authenticator-threads.patch
index 971fc83aa8..971fc83aa8 100644
--- a/patches/server/0108-Cache-user-authenticator-threads.patch
+++ b/patches/server/0116-Cache-user-authenticator-threads.patch
diff --git a/patches/server/0109-Allow-Reloading-of-Command-Aliases.patch b/patches/server/0117-Allow-Reloading-of-Command-Aliases.patch
index 6cc98da194..a203b2084c 100644
--- a/patches/server/0109-Allow-Reloading-of-Command-Aliases.patch
+++ b/patches/server/0117-Allow-Reloading-of-Command-Aliases.patch
@@ -6,7 +6,7 @@ Subject: [PATCH] Allow Reloading of Command Aliases
Reload the aliases stored in commands.yml
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-index cc4bd65d8f9f3824e77e4509a8f0dbda5c2f01a6..34b35a4e2e723f4bfe6773da1e9958badadec221 100644
+index 6e28fd088ff19bcd2206f2d8decf72184d109baf..5c9a4327232c1bdf219a66f66ef8ad699104be41 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -2563,5 +2563,24 @@ public final class CraftServer implements Server {
diff --git a/patches/server/0110-Add-source-to-PlayerExpChangeEvent.patch b/patches/server/0118-Add-source-to-PlayerExpChangeEvent.patch
index e290b2ac51..e290b2ac51 100644
--- a/patches/server/0110-Add-source-to-PlayerExpChangeEvent.patch
+++ b/patches/server/0118-Add-source-to-PlayerExpChangeEvent.patch
diff --git a/patches/server/0111-Add-ProjectileCollideEvent.patch b/patches/server/0119-Add-ProjectileCollideEvent.patch
index 150e864a9e..150e864a9e 100644
--- a/patches/server/0111-Add-ProjectileCollideEvent.patch
+++ b/patches/server/0119-Add-ProjectileCollideEvent.patch
diff --git a/patches/server/0112-Prevent-Pathfinding-out-of-World-Border.patch b/patches/server/0120-Prevent-Pathfinding-out-of-World-Border.patch
index 266eb9f28f..266eb9f28f 100644
--- a/patches/server/0112-Prevent-Pathfinding-out-of-World-Border.patch
+++ b/patches/server/0120-Prevent-Pathfinding-out-of-World-Border.patch
diff --git a/patches/server/0113-Optimize-World.isLoaded-BlockPosition-Z.patch b/patches/server/0121-Optimize-World.isLoaded-BlockPosition-Z.patch
index 2756e56e5d..2756e56e5d 100644
--- a/patches/server/0113-Optimize-World.isLoaded-BlockPosition-Z.patch
+++ b/patches/server/0121-Optimize-World.isLoaded-BlockPosition-Z.patch
diff --git a/patches/server/0114-Bound-Treasure-Maps-to-World-Border.patch b/patches/server/0122-Bound-Treasure-Maps-to-World-Border.patch
index 01b6cd61ca..01b6cd61ca 100644
--- a/patches/server/0114-Bound-Treasure-Maps-to-World-Border.patch
+++ b/patches/server/0122-Bound-Treasure-Maps-to-World-Border.patch
diff --git a/patches/server/0115-Configurable-Cartographer-Treasure-Maps.patch b/patches/server/0123-Configurable-Cartographer-Treasure-Maps.patch
index 25ad0e6acc..25ad0e6acc 100644
--- a/patches/server/0115-Configurable-Cartographer-Treasure-Maps.patch
+++ b/patches/server/0123-Configurable-Cartographer-Treasure-Maps.patch
diff --git a/patches/server/0116-Optimize-ItemStack.isEmpty.patch b/patches/server/0124-Optimize-ItemStack.isEmpty.patch
index cb004037bf..cb004037bf 100644
--- a/patches/server/0116-Optimize-ItemStack.isEmpty.patch
+++ b/patches/server/0124-Optimize-ItemStack.isEmpty.patch
diff --git a/patches/server/0117-Add-API-methods-to-control-if-armour-stands-can-move.patch b/patches/server/0125-Add-API-methods-to-control-if-armour-stands-can-move.patch
index 6b19100733..6b19100733 100644
--- a/patches/server/0117-Add-API-methods-to-control-if-armour-stands-can-move.patch
+++ b/patches/server/0125-Add-API-methods-to-control-if-armour-stands-can-move.patch
diff --git a/patches/server/0118-String-based-Action-Bar-API.patch b/patches/server/0126-String-based-Action-Bar-API.patch
index 44010d4ab0..993e5b8cbd 100644
--- a/patches/server/0118-String-based-Action-Bar-API.patch
+++ b/patches/server/0126-String-based-Action-Bar-API.patch
@@ -26,7 +26,7 @@ index 32ef3edebe94a2014168b7e438752a80b2687e5f..ab6c58eed6707ab7b0aa3e7549a871ad
// Paper end
buf.writeComponent(this.text);
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
-index 16103cea67ec657edfd57b2a1d582794efeac4b6..198d679a0f46324b2ec483d474cff0829bbd6844 100644
+index da91150f7462c2743d7394b148ddb52e9af8b797..a5418b1c78e1f1eb9f552450367717fee9487193 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -274,6 +274,26 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
diff --git a/patches/server/0119-Properly-fix-item-duplication-bug.patch b/patches/server/0127-Properly-fix-item-duplication-bug.patch
index 6126f06bb0..b290e5f8c3 100644
--- a/patches/server/0119-Properly-fix-item-duplication-bug.patch
+++ b/patches/server/0127-Properly-fix-item-duplication-bug.patch
@@ -6,10 +6,10 @@ Subject: [PATCH] Properly fix item duplication bug
Credit to prplz for figuring out the real issue
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-index 5b568d8f3f2e8bd466ac1edae9cafc602a226175..69dc4063ae0a3e7271ce0e4ca79c0b059de24bc8 100644
+index 4d8dfe375f5b3b9e5cfc12a6af0b87ae78f9b764..5d214b7dd4f6d7feff0a1904ce6573cffd258a1c 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-@@ -2194,7 +2194,7 @@ public class ServerPlayer extends Player {
+@@ -2210,7 +2210,7 @@ public class ServerPlayer extends Player {
@Override
public boolean isImmobile() {
@@ -19,10 +19,10 @@ index 5b568d8f3f2e8bd466ac1edae9cafc602a226175..69dc4063ae0a3e7271ce0e4ca79c0b05
@Override
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-index 952ad96c310b8d1285e1dd07ec224d5005d5c8cc..2b54fe257db874cb74a9bd002de8721d47409e6a 100644
+index c8f9223f750ec0825c45288d52df149f94748d5d..98f168c72ae9c7636ab07a14daf8b7afb1b3feec 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-@@ -3274,7 +3274,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
+@@ -3281,7 +3281,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
}
public final boolean isDisconnected() {
diff --git a/patches/server/0120-Firework-API-s.patch b/patches/server/0128-Firework-API-s.patch
index cde42af88b..cde42af88b 100644
--- a/patches/server/0120-Firework-API-s.patch
+++ b/patches/server/0128-Firework-API-s.patch
diff --git a/patches/server/0121-PlayerTeleportEndGatewayEvent.patch b/patches/server/0129-PlayerTeleportEndGatewayEvent.patch
index 65f98958b1..65f98958b1 100644
--- a/patches/server/0121-PlayerTeleportEndGatewayEvent.patch
+++ b/patches/server/0129-PlayerTeleportEndGatewayEvent.patch
diff --git a/patches/server/0122-Provide-E-TE-Chunk-count-stat-methods.patch b/patches/server/0130-Provide-E-TE-Chunk-count-stat-methods.patch
index 91494190e3..2558009b17 100644
--- a/patches/server/0122-Provide-E-TE-Chunk-count-stat-methods.patch
+++ b/patches/server/0130-Provide-E-TE-Chunk-count-stat-methods.patch
@@ -20,10 +20,10 @@ index c8350eae421f5655de490c420dcb284c78f58f62..4e843d9e28f7775faba3e47ca5a725f7
private final List<TickingBlockEntity> pendingBlockEntityTickers = Lists.newArrayList();
private boolean tickingBlockEntities;
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-index 40d6b00fb40db167c6c80b6a3f79eb82d08cdfb9..40dd3913ac630899206a506ea9dfc58de634f391 100644
+index 0ed46cdd443ac42a7d57ee59f6f04fd9e9259c16..b2e693b6a799568c6196c1f805f0153ea69b8bd2 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-@@ -152,6 +152,57 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+@@ -152,6 +152,56 @@ public class CraftWorld extends CraftRegionAccessor implements World {
private final CraftPersistentDataContainer persistentDataContainer = new CraftPersistentDataContainer(CraftWorld.DATA_TYPE_REGISTRY);
private net.kyori.adventure.pointer.Pointers adventure$pointers; // Paper - implement pointers
@@ -42,9 +42,8 @@ index 40d6b00fb40db167c6c80b6a3f79eb82d08cdfb9..40dd3913ac630899206a506ea9dfc58d
+ @Override
+ public int getTileEntityCount() {
+ // We don't use the full world tile entity list, so we must iterate chunks
-+ Long2ObjectLinkedOpenHashMap<ChunkHolder> chunks = world.getChunkSource().chunkMap.visibleChunkMap;
+ int size = 0;
-+ for (ChunkHolder playerchunk : chunks.values()) {
++ for (ChunkHolder playerchunk : net.minecraft.server.ChunkSystem.getVisibleChunkHolders(this.world)) {
+ net.minecraft.world.level.chunk.LevelChunk chunk = playerchunk.getTickingChunk();
+ if (chunk == null) {
+ continue;
@@ -63,7 +62,7 @@ index 40d6b00fb40db167c6c80b6a3f79eb82d08cdfb9..40dd3913ac630899206a506ea9dfc58d
+ public int getChunkCount() {
+ int ret = 0;
+
-+ for (ChunkHolder chunkHolder : world.getChunkSource().chunkMap.visibleChunkMap.values()) {
++ for (ChunkHolder chunkHolder : net.minecraft.server.ChunkSystem.getVisibleChunkHolders(this.world)) {
+ if (chunkHolder.getTickingChunk() != null) {
+ ++ret;
+ }
diff --git a/patches/server/0123-Enforce-Sync-Player-Saves.patch b/patches/server/0131-Enforce-Sync-Player-Saves.patch
index a514731ac4..84ab1f0188 100644
--- a/patches/server/0123-Enforce-Sync-Player-Saves.patch
+++ b/patches/server/0131-Enforce-Sync-Player-Saves.patch
@@ -7,10 +7,10 @@ Saving players async is extremely dangerous. This will force it to main
the same way we handle async chunk loads.
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
-index b4f29bed0332489ccae54cfb7a7f90e4df89743f..23687ae4a06be741a82cec1178d891aed4640084 100644
+index a474241c66a532791d9734ab9a9f6529f5414169..40d1f5433f3f1277663c65be2f85aaee5652f88a 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
-@@ -1041,11 +1041,13 @@ public abstract class PlayerList {
+@@ -1042,11 +1042,13 @@ public abstract class PlayerList {
}
public void saveAll() {
diff --git a/patches/server/0124-Don-t-allow-entities-to-ride-themselves-572.patch b/patches/server/0132-Don-t-allow-entities-to-ride-themselves-572.patch
index 89c1907eee..5f23a31a41 100644
--- a/patches/server/0124-Don-t-allow-entities-to-ride-themselves-572.patch
+++ b/patches/server/0132-Don-t-allow-entities-to-ride-themselves-572.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] Don't allow entities to ride themselves - #572
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
-index 0fe534337ea72b338583039644f1f2b5be76d385..0c9cabfb5ff3733ac857889482474555b17b4e5c 100644
+index 32d230dc6968306dd6e322ffd6a820380e3c88b1..f7a8c947ef639d0d9cf8e527f8a0072432cba0c5 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -2319,6 +2319,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
diff --git a/patches/server/0125-ExperienceOrbs-API-for-Reason-Source-Triggering-play.patch b/patches/server/0133-ExperienceOrbs-API-for-Reason-Source-Triggering-play.patch
index a88248a9ab..a88248a9ab 100644
--- a/patches/server/0125-ExperienceOrbs-API-for-Reason-Source-Triggering-play.patch
+++ b/patches/server/0133-ExperienceOrbs-API-for-Reason-Source-Triggering-play.patch
diff --git a/patches/server/0126-Cap-Entity-Collisions.patch b/patches/server/0134-Cap-Entity-Collisions.patch
index 9c60d092a6..9fc626bec9 100644
--- a/patches/server/0126-Cap-Entity-Collisions.patch
+++ b/patches/server/0134-Cap-Entity-Collisions.patch
@@ -12,7 +12,7 @@ just as it does in Vanilla, but entity pushing logic will be capped.
You can set this to 0 to disable collisions.
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
-index 0c9cabfb5ff3733ac857889482474555b17b4e5c..778549f30d941352014983adb0e7a4457e6eb11b 100644
+index f7a8c947ef639d0d9cf8e527f8a0072432cba0c5..a676fa481ad3e3ac60cf5ba9d86acd61bea329ca 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -379,6 +379,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
diff --git a/patches/server/0127-Remove-CraftScheduler-Async-Task-Debugger.patch b/patches/server/0135-Remove-CraftScheduler-Async-Task-Debugger.patch
index eacad1fb97..eacad1fb97 100644
--- a/patches/server/0127-Remove-CraftScheduler-Async-Task-Debugger.patch
+++ b/patches/server/0135-Remove-CraftScheduler-Async-Task-Debugger.patch
diff --git a/patches/server/0128-Do-not-let-armorstands-drown.patch b/patches/server/0136-Do-not-let-armorstands-drown.patch
index 948bf3a496..948bf3a496 100644
--- a/patches/server/0128-Do-not-let-armorstands-drown.patch
+++ b/patches/server/0136-Do-not-let-armorstands-drown.patch
diff --git a/patches/server/0129-Make-targetSize-more-aggressive-in-the-chunk-unload-.patch b/patches/server/0137-Make-targetSize-more-aggressive-in-the-chunk-unload-.patch
index bfb9bf42db..6a3c1b57fe 100644
--- a/patches/server/0129-Make-targetSize-more-aggressive-in-the-chunk-unload-.patch
+++ b/patches/server/0137-Make-targetSize-more-aggressive-in-the-chunk-unload-.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Make targetSize more aggressive in the chunk unload queue
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
-index 1c73599e37e9b830ff0ab9bcc9edc7b63daa6ca1..dd318c213742299fca1335fadf1f4465b471d7ea 100644
+index 4af8cee31d20e5dcec510439795e7e90fc668128..e086135936e4f6c109cd09a4e4df350702b3510a 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
-@@ -233,7 +233,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -247,7 +247,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
this.entityMap = new Int2ObjectOpenHashMap();
this.chunkTypeCache = new Long2ByteOpenHashMap();
this.chunkSaveCooldowns = new Long2LongOpenHashMap();
@@ -17,15 +17,15 @@ index 1c73599e37e9b830ff0ab9bcc9edc7b63daa6ca1..dd318c213742299fca1335fadf1f4465
this.structureTemplateManager = structureTemplateManager;
Path path = session.getDimensionPath(world.dimension());
-@@ -588,7 +588,6 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -674,7 +674,6 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
private void processUnloads(BooleanSupplier shouldKeepTicking) {
LongIterator longiterator = this.toDrop.iterator();
-
for (int i = 0; longiterator.hasNext() && (shouldKeepTicking.getAsBoolean() || i < 200 || this.toDrop.size() > 2000); longiterator.remove()) {
long j = longiterator.nextLong();
- ChunkHolder playerchunk = (ChunkHolder) this.updatingChunkMap.remove(j);
-@@ -601,7 +600,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+ ChunkHolder playerchunk = this.updatingChunks.queueRemove(j); // Paper - Don't copy
+@@ -688,7 +687,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
}
}
diff --git a/patches/server/0130-Properly-handle-async-calls-to-restart-the-server.patch b/patches/server/0138-Properly-handle-async-calls-to-restart-the-server.patch
index 22e1461d66..dda388b4c6 100644
--- a/patches/server/0130-Properly-handle-async-calls-to-restart-the-server.patch
+++ b/patches/server/0138-Properly-handle-async-calls-to-restart-the-server.patch
@@ -30,7 +30,7 @@ will have plugins and worlds saving to the disk has a high potential to result
in corruption/dataloss.
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
-index 8c9bc0995f5b59e05a4ecebbe2bfb5d65ec92dcf..81e54058bc5e034b076e2bad1115c53950b3b39b 100644
+index da790861a3689195446040e8e7d2f898eee3068e..7f392cb74778de9854704895337bc78901552b44 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -221,6 +221,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -64,10 +64,10 @@ index 8c9bc0995f5b59e05a4ecebbe2bfb5d65ec92dcf..81e54058bc5e034b076e2bad1115c539
if (flag) {
try {
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
-index aadeb9c63436214d541c563179ed7a32bfdd6d88..dee794f1128309c87d02b1a6a19cf9db314994e3 100644
+index 40d1f5433f3f1277663c65be2f85aaee5652f88a..0a1684609ae155f99959b4cb4db3a1cf7234c54b 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
-@@ -1152,8 +1152,15 @@ public abstract class PlayerList {
+@@ -1153,8 +1153,15 @@ public abstract class PlayerList {
}
public void removeAll() {
diff --git a/patches/server/0131-Add-option-to-make-parrots-stay-on-shoulders-despite.patch b/patches/server/0139-Add-option-to-make-parrots-stay-on-shoulders-despite.patch
index 62dc6bafbf..291c3715c9 100644
--- a/patches/server/0131-Add-option-to-make-parrots-stay-on-shoulders-despite.patch
+++ b/patches/server/0139-Add-option-to-make-parrots-stay-on-shoulders-despite.patch
@@ -11,10 +11,10 @@ I suspect Mojang may switch to this behavior before full release.
To be converted into a Paper-API event at some point in the future?
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-index 2b54fe257db874cb74a9bd002de8721d47409e6a..c06fbadc3960a31b376f814ad050f34954728762 100644
+index 98f168c72ae9c7636ab07a14daf8b7afb1b3feec..f3360ebf43d973606682fe85bc3240a84a0f0123 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-@@ -2455,6 +2455,13 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
+@@ -2462,6 +2462,13 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
switch (packet.getAction()) {
case PRESS_SHIFT_KEY:
this.player.setShiftKeyDown(true);
diff --git a/patches/server/0132-Add-configuration-option-to-prevent-player-names-fro.patch b/patches/server/0140-Add-configuration-option-to-prevent-player-names-fro.patch
index f6d8e60cf3..b839f69290 100644
--- a/patches/server/0132-Add-configuration-option-to-prevent-player-names-fro.patch
+++ b/patches/server/0140-Add-configuration-option-to-prevent-player-names-fro.patch
@@ -6,7 +6,7 @@ Subject: [PATCH] Add configuration option to prevent player names from being
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-index 34b35a4e2e723f4bfe6773da1e9958badadec221..593b998592cc340f8ff1f8806394fea7e0871cf0 100644
+index 5c9a4327232c1bdf219a66f66ef8ad699104be41..6109763453327f49a15c677a3af8f2de959b58cc 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -2582,5 +2582,10 @@ public final class CraftServer implements Server {
diff --git a/patches/server/0133-Use-TerminalConsoleAppender-for-console-improvements.patch b/patches/server/0141-Use-TerminalConsoleAppender-for-console-improvements.patch
index cdb6d9a12c..41f10d95e2 100644
--- a/patches/server/0133-Use-TerminalConsoleAppender-for-console-improvements.patch
+++ b/patches/server/0141-Use-TerminalConsoleAppender-for-console-improvements.patch
@@ -112,7 +112,7 @@ index 0000000000000000000000000000000000000000..685deaa0e5d1ddc13e3a7c0471b1cfcf
+
+}
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
-index 81e54058bc5e034b076e2bad1115c53950b3b39b..f4effe6f006df5209cd130f42ff1cd207547bbc5 100644
+index 7f392cb74778de9854704895337bc78901552b44..2d474f3bf38545d2703f1f8f80419dc774e15bf6 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -156,7 +156,7 @@ import org.slf4j.Logger;
@@ -222,7 +222,7 @@ index 5b2980866ae3cd78f1852b0ad396ff1967ddfc16..9411e5664c0067f976018fe19b1e7403
System.setOut(IoBuilder.forLogger(logger).setLevel(Level.INFO).buildPrintStream());
System.setErr(IoBuilder.forLogger(logger).setLevel(Level.WARN).buildPrintStream());
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
-index dee794f1128309c87d02b1a6a19cf9db314994e3..73cf0363ebbe383348f8bcc79a85dcfa4d147443 100644
+index 0a1684609ae155f99959b4cb4db3a1cf7234c54b..1b021f6048f6030bb8d7b59b39f5e829f1687365 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -160,8 +160,7 @@ public abstract class PlayerList {
diff --git a/patches/server/0134-provide-a-configurable-option-to-disable-creeper-lin.patch b/patches/server/0142-provide-a-configurable-option-to-disable-creeper-lin.patch
index d5c14819e2..d5c14819e2 100644
--- a/patches/server/0134-provide-a-configurable-option-to-disable-creeper-lin.patch
+++ b/patches/server/0142-provide-a-configurable-option-to-disable-creeper-lin.patch
diff --git a/patches/server/0135-Item-canEntityPickup.patch b/patches/server/0143-Item-canEntityPickup.patch
index 38236cc42a..38236cc42a 100644
--- a/patches/server/0135-Item-canEntityPickup.patch
+++ b/patches/server/0143-Item-canEntityPickup.patch
diff --git a/patches/server/0136-PlayerPickupItemEvent-setFlyAtPlayer.patch b/patches/server/0144-PlayerPickupItemEvent-setFlyAtPlayer.patch
index 6e987d76ed..6e987d76ed 100644
--- a/patches/server/0136-PlayerPickupItemEvent-setFlyAtPlayer.patch
+++ b/patches/server/0144-PlayerPickupItemEvent-setFlyAtPlayer.patch
diff --git a/patches/server/0137-PlayerAttemptPickupItemEvent.patch b/patches/server/0145-PlayerAttemptPickupItemEvent.patch
index deec8f3a7d..deec8f3a7d 100644
--- a/patches/server/0137-PlayerAttemptPickupItemEvent.patch
+++ b/patches/server/0145-PlayerAttemptPickupItemEvent.patch
diff --git a/patches/server/0138-Do-not-submit-profile-lookups-to-worldgen-threads.patch b/patches/server/0146-Do-not-submit-profile-lookups-to-worldgen-threads.patch
index b2385e0d42..b2385e0d42 100644
--- a/patches/server/0138-Do-not-submit-profile-lookups-to-worldgen-threads.patch
+++ b/patches/server/0146-Do-not-submit-profile-lookups-to-worldgen-threads.patch
diff --git a/patches/server/0139-Add-UnknownCommandEvent.patch b/patches/server/0147-Add-UnknownCommandEvent.patch
index 110c1555e9..d9cabca3ac 100644
--- a/patches/server/0139-Add-UnknownCommandEvent.patch
+++ b/patches/server/0147-Add-UnknownCommandEvent.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] Add UnknownCommandEvent
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-index 4d15fb22c0b12ec438584c672c03a41ea50c4133..13a6582765c565197ef8d1013b428c45e2ac5d66 100644
+index 8da0beff6a7937130ecd99dd46880da0d4a16a1a..c4641b210b7d4f09ed84ad1c25d9e7b0b6b97303 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -892,7 +892,13 @@ public final class CraftServer implements Server {
diff --git a/patches/server/0140-Basic-PlayerProfile-API.patch b/patches/server/0148-Basic-PlayerProfile-API.patch
index 6777b46e1e..44cd475f32 100644
--- a/patches/server/0140-Basic-PlayerProfile-API.patch
+++ b/patches/server/0148-Basic-PlayerProfile-API.patch
@@ -555,7 +555,7 @@ index 0000000000000000000000000000000000000000..7ac27392a8647ef7d0dc78efe78703e9
+ @NotNull GameProfile buildGameProfile();
+}
diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java
-index 9f292deee1b793d52b5774304318e940128d1e26..0cf818fceddd76e7704fdc6625456787856b2815 100644
+index 3023bf9d1e7ead3afedc7f72a85ee65f6cf2016c..98cd851cdc67ecd9296ec5a8e56141638e108109 100644
--- a/src/main/java/net/minecraft/server/MCUtil.java
+++ b/src/main/java/net/minecraft/server/MCUtil.java
@@ -1,5 +1,7 @@
@@ -564,17 +564,17 @@ index 9f292deee1b793d52b5774304318e940128d1e26..0cf818fceddd76e7704fdc6625456787
+import com.destroystokyo.paper.profile.CraftPlayerProfile;
+import com.destroystokyo.paper.profile.PlayerProfile;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
- import it.unimi.dsi.fastutil.objects.ObjectRBTreeSet;
- import java.lang.ref.Cleaner;
-@@ -11,6 +13,7 @@ import net.minecraft.world.level.ChunkPos;
- import net.minecraft.world.level.ClipContext;
- import net.minecraft.world.level.Level;
+ import com.google.gson.JsonArray;
+ import com.google.gson.JsonObject;
+@@ -23,6 +25,7 @@ import net.minecraft.world.level.Level;
+ import net.minecraft.world.level.chunk.ChunkAccess;
+ import net.minecraft.world.level.chunk.ChunkStatus;
import org.apache.commons.lang.exception.ExceptionUtils;
+import com.mojang.authlib.GameProfile;
import org.bukkit.Location;
import org.bukkit.block.BlockFace;
import org.bukkit.craftbukkit.CraftWorld;
-@@ -355,6 +358,10 @@ public final class MCUtil {
+@@ -370,6 +373,10 @@ public final class MCUtil {
return run.get();
}
@@ -586,7 +586,7 @@ index 9f292deee1b793d52b5774304318e940128d1e26..0cf818fceddd76e7704fdc6625456787
* Calculates distance between 2 entities
* @param e1
diff --git a/src/main/java/net/minecraft/server/Main.java b/src/main/java/net/minecraft/server/Main.java
-index a48a12a31a3d09a9373b688dcc093035f8f8a300..97b29bcb20e199c2d02457f8025e67e2d4a925fc 100644
+index 0c59ca1a22449893adcfa851198f057ce69bb7e3..8fda43173012ed3134ed1f114143ceaad66cae4a 100644
--- a/src/main/java/net/minecraft/server/Main.java
+++ b/src/main/java/net/minecraft/server/Main.java
@@ -138,7 +138,7 @@ public class Main {
@@ -621,7 +621,7 @@ index 2a0cf0a8a79c09566c598197fc6f8c447d4bbd72..5e3bc0590e59770490b1c6c818d99be0
String s1 = name.toLowerCase(Locale.ROOT);
GameProfileCache.GameProfileInfo usercache_usercacheentry = (GameProfileCache.GameProfileInfo) this.profilesByName.get(s1);
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-index 13a6582765c565197ef8d1013b428c45e2ac5d66..adb3c54932a90c4881e6db0ed037d033220e9a7e 100644
+index c4641b210b7d4f09ed84ad1c25d9e7b0b6b97303..90d88637b5690524d1899541abbb310d330d0e50 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -244,6 +244,9 @@ import org.yaml.snakeyaml.error.MarkedYAMLException;
diff --git a/patches/server/0141-Shoulder-Entities-Release-API.patch b/patches/server/0149-Shoulder-Entities-Release-API.patch
index 23582ab7cc..23582ab7cc 100644
--- a/patches/server/0141-Shoulder-Entities-Release-API.patch
+++ b/patches/server/0149-Shoulder-Entities-Release-API.patch
diff --git a/patches/server/0142-Profile-Lookup-Events.patch b/patches/server/0150-Profile-Lookup-Events.patch
index a9a4210f19..a9a4210f19 100644
--- a/patches/server/0142-Profile-Lookup-Events.patch
+++ b/patches/server/0150-Profile-Lookup-Events.patch
diff --git a/patches/server/0143-Block-player-logins-during-server-shutdown.patch b/patches/server/0151-Block-player-logins-during-server-shutdown.patch
index dfd3414f60..dfd3414f60 100644
--- a/patches/server/0143-Block-player-logins-during-server-shutdown.patch
+++ b/patches/server/0151-Block-player-logins-during-server-shutdown.patch
diff --git a/patches/server/0144-Entity-fromMobSpawner.patch b/patches/server/0152-Entity-fromMobSpawner.patch
index 64a013f0a4..fa68f366e4 100644
--- a/patches/server/0144-Entity-fromMobSpawner.patch
+++ b/patches/server/0152-Entity-fromMobSpawner.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] Entity#fromMobSpawner()
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
-index 778549f30d941352014983adb0e7a4457e6eb11b..2e7b3de046bace7c4c275654a0f1e9066790db0c 100644
+index a676fa481ad3e3ac60cf5ba9d86acd61bea329ca..81fd2e443de0b85b340b48e66bc5fb0acad5d60a 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -380,6 +380,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
@@ -49,10 +49,10 @@ index e5b56a85d76d1417dda2d14b1b03850bbb070f4c..5304b0455b070006922e1b5471e9c0ab
if (org.bukkit.craftbukkit.event.CraftEventFactory.callSpawnerSpawnEvent(entity, pos).isCancelled()) {
Entity vehicle = entity.getVehicle();
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
-index e1ae00c1639b4ff18e061d86b006ff733494bb00..41753b72ac6fdf0314d60dbe1ffb60e79b3e4af8 100644
+index 8b4f1ef248d0b13927cbf634a0e2a97eb93c8ae4..5a8e31d3e1078559f17151a8f9a9cbaec58b1942 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
-@@ -1212,5 +1212,10 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
+@@ -1243,5 +1243,10 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
//noinspection ConstantConditions
return originVector.toLocation(world);
}
diff --git a/patches/server/0145-Improve-the-Saddle-API-for-Horses.patch b/patches/server/0153-Improve-the-Saddle-API-for-Horses.patch
index ccd3b7baf4..ccd3b7baf4 100644
--- a/patches/server/0145-Improve-the-Saddle-API-for-Horses.patch
+++ b/patches/server/0153-Improve-the-Saddle-API-for-Horses.patch
diff --git a/patches/server/0146-Implement-ensureServerConversions-API.patch b/patches/server/0154-Implement-ensureServerConversions-API.patch
index f98e7f543c..f98e7f543c 100644
--- a/patches/server/0146-Implement-ensureServerConversions-API.patch
+++ b/patches/server/0154-Implement-ensureServerConversions-API.patch
diff --git a/patches/server/0147-Implement-getI18NDisplayName.patch b/patches/server/0155-Implement-getI18NDisplayName.patch
index 7011d8a566..7011d8a566 100644
--- a/patches/server/0147-Implement-getI18NDisplayName.patch
+++ b/patches/server/0155-Implement-getI18NDisplayName.patch
diff --git a/patches/server/0148-ProfileWhitelistVerifyEvent.patch b/patches/server/0156-ProfileWhitelistVerifyEvent.patch
index fbd026ca4e..126a4ea9c1 100644
--- a/patches/server/0148-ProfileWhitelistVerifyEvent.patch
+++ b/patches/server/0156-ProfileWhitelistVerifyEvent.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] ProfileWhitelistVerifyEvent
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
-index 258eee0f5310224b089895745ff11e482fc36dca..29f761432be28b5089caab9338b3bff41f4f8f07 100644
+index 1b021f6048f6030bb8d7b59b39f5e829f1687365..bf5cfdae384e44b3cef5d7edb69a559803f583a4 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
-@@ -620,9 +620,9 @@ public abstract class PlayerList {
+@@ -621,9 +621,9 @@ public abstract class PlayerList {
// return chatmessage;
event.disallow(PlayerLoginEvent.Result.KICK_BANNED, PaperAdventure.asAdventure(ichatmutablecomponent)); // Paper - Adventure
@@ -21,7 +21,7 @@ index 258eee0f5310224b089895745ff11e482fc36dca..29f761432be28b5089caab9338b3bff4
} else if (this.getIpBans().isBanned(socketaddress) && !this.getIpBans().get(socketaddress).hasExpired()) {
IpBanListEntry ipbanentry = this.ipBans.get(socketaddress);
-@@ -1004,7 +1004,23 @@ public abstract class PlayerList {
+@@ -1005,7 +1005,23 @@ public abstract class PlayerList {
}
public boolean isWhiteListed(GameProfile profile) {
diff --git a/patches/server/0149-Fix-this-stupid-bullshit.patch b/patches/server/0157-Fix-this-stupid-bullshit.patch
index 0a6c46fbe4..0a6c46fbe4 100644
--- a/patches/server/0149-Fix-this-stupid-bullshit.patch
+++ b/patches/server/0157-Fix-this-stupid-bullshit.patch
diff --git a/patches/server/0150-LivingEntity-setKiller.patch b/patches/server/0158-LivingEntity-setKiller.patch
index c8eb4f6720..c8eb4f6720 100644
--- a/patches/server/0150-LivingEntity-setKiller.patch
+++ b/patches/server/0158-LivingEntity-setKiller.patch
diff --git a/patches/server/0151-Ocelot-despawns-should-honor-nametags-and-leash.patch b/patches/server/0159-Ocelot-despawns-should-honor-nametags-and-leash.patch
index 884de65442..884de65442 100644
--- a/patches/server/0151-Ocelot-despawns-should-honor-nametags-and-leash.patch
+++ b/patches/server/0159-Ocelot-despawns-should-honor-nametags-and-leash.patch
diff --git a/patches/server/0152-Reset-spawner-timer-when-spawner-event-is-cancelled.patch b/patches/server/0160-Reset-spawner-timer-when-spawner-event-is-cancelled.patch
index c47d4472ba..c47d4472ba 100644
--- a/patches/server/0152-Reset-spawner-timer-when-spawner-event-is-cancelled.patch
+++ b/patches/server/0160-Reset-spawner-timer-when-spawner-event-is-cancelled.patch
diff --git a/patches/server/0153-Allow-specifying-a-custom-authentication-servers-dow.patch b/patches/server/0161-Allow-specifying-a-custom-authentication-servers-dow.patch
index 2392b1238a..2392b1238a 100644
--- a/patches/server/0153-Allow-specifying-a-custom-authentication-servers-dow.patch
+++ b/patches/server/0161-Allow-specifying-a-custom-authentication-servers-dow.patch
diff --git a/patches/server/0154-Handle-plugin-prefixes-using-Log4J-configuration.patch b/patches/server/0162-Handle-plugin-prefixes-using-Log4J-configuration.patch
index 24e5ff4f30..24e5ff4f30 100644
--- a/patches/server/0154-Handle-plugin-prefixes-using-Log4J-configuration.patch
+++ b/patches/server/0162-Handle-plugin-prefixes-using-Log4J-configuration.patch
diff --git a/patches/server/0155-Improve-Log4J-Configuration-Plugin-Loggers.patch b/patches/server/0163-Improve-Log4J-Configuration-Plugin-Loggers.patch
index 5afb9562c0..5afb9562c0 100644
--- a/patches/server/0155-Improve-Log4J-Configuration-Plugin-Loggers.patch
+++ b/patches/server/0163-Improve-Log4J-Configuration-Plugin-Loggers.patch
diff --git a/patches/server/0156-Add-PlayerJumpEvent.patch b/patches/server/0164-Add-PlayerJumpEvent.patch
index 0037d31c81..c6cc300797 100644
--- a/patches/server/0156-Add-PlayerJumpEvent.patch
+++ b/patches/server/0164-Add-PlayerJumpEvent.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Add PlayerJumpEvent
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-index c06fbadc3960a31b376f814ad050f34954728762..9eb204ba4df5064fcca40c9445a5fc6a10d1b3aa 100644
+index f3360ebf43d973606682fe85bc3240a84a0f0123..b44fd3e73d2d15736ac2bbcc7d99ae44c7459d4b 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-@@ -1286,7 +1286,34 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
+@@ -1293,7 +1293,34 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
boolean flag = d8 > 0.0D;
if (this.player.isOnGround() && !packet.isOnGround() && flag) {
diff --git a/patches/server/0157-handle-ServerboundKeepAlivePacket-async.patch b/patches/server/0165-handle-ServerboundKeepAlivePacket-async.patch
index 05c48ce612..39a68612c6 100644
--- a/patches/server/0157-handle-ServerboundKeepAlivePacket-async.patch
+++ b/patches/server/0165-handle-ServerboundKeepAlivePacket-async.patch
@@ -15,10 +15,10 @@ also adding some additional logging in order to help work out what is causing
random disconnections for clients.
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-index 9eb204ba4df5064fcca40c9445a5fc6a10d1b3aa..96091153862433ffe2fdc90c00f1cc6be02e8977 100644
+index b44fd3e73d2d15736ac2bbcc7d99ae44c7459d4b..c6330fa43f205c28f3a494269933482c14f75afb 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-@@ -3233,14 +3233,18 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
+@@ -3240,14 +3240,18 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
@Override
public void handleKeepAlive(ServerboundKeepAlivePacket packet) {
diff --git a/patches/server/0158-Expose-client-protocol-version-and-virtual-host.patch b/patches/server/0166-Expose-client-protocol-version-and-virtual-host.patch
index 424b1bde62..e5c31b05c4 100644
--- a/patches/server/0158-Expose-client-protocol-version-and-virtual-host.patch
+++ b/patches/server/0166-Expose-client-protocol-version-and-virtual-host.patch
@@ -60,7 +60,7 @@ index 0000000000000000000000000000000000000000..a5a7624f1f372a26b982836cd31cff15
+
+}
diff --git a/src/main/java/net/minecraft/network/Connection.java b/src/main/java/net/minecraft/network/Connection.java
-index c06f1e1f08c3a854031b48ecc49e35aeb0d9b628..b132a5ca649833043b81578a2439901eaf4c4ab5 100644
+index 9b96d05094c3b83f6388d479fdca8800453ccd1d..308b720a58320aab1e2616542bbdd2e2fc5869ee 100644
--- a/src/main/java/net/minecraft/network/Connection.java
+++ b/src/main/java/net/minecraft/network/Connection.java
@@ -89,6 +89,10 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
@@ -90,7 +90,7 @@ index 9016aced079108aeae09f030a672467a953ef93f..4170bda451df3db43e7d57d87d1abb81
@Override
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
-index 198d679a0f46324b2ec483d474cff0829bbd6844..1c620dc2e798c9d4f0816753362cab8564037ca0 100644
+index a5418b1c78e1f1eb9f552450367717fee9487193..460e237a3237d5965b2ef85d32113682ee04e52d 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -218,6 +218,20 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
diff --git a/patches/server/0159-revert-serverside-behavior-of-keepalives.patch b/patches/server/0167-revert-serverside-behavior-of-keepalives.patch
index 27d0bf3171..8657cdbcbe 100644
--- a/patches/server/0159-revert-serverside-behavior-of-keepalives.patch
+++ b/patches/server/0167-revert-serverside-behavior-of-keepalives.patch
@@ -17,7 +17,7 @@ from networking or during connections flood of chunk packets on slower clients,
at the cost of dead connections being kept open for longer.
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-index 96091153862433ffe2fdc90c00f1cc6be02e8977..90b09d4fcb267dff4ab3c910948876a4408abcd1 100644
+index c6330fa43f205c28f3a494269933482c14f75afb..322ecd7671c9b1a6c359455d47ec617b7da00bdc 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -256,7 +256,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
diff --git a/patches/server/0160-Send-attack-SoundEffects-only-to-players-who-can-see.patch b/patches/server/0168-Send-attack-SoundEffects-only-to-players-who-can-see.patch
index edadd2cc60..edadd2cc60 100644
--- a/patches/server/0160-Send-attack-SoundEffects-only-to-players-who-can-see.patch
+++ b/patches/server/0168-Send-attack-SoundEffects-only-to-players-who-can-see.patch
diff --git a/patches/server/0161-Add-PlayerArmorChangeEvent.patch b/patches/server/0169-Add-PlayerArmorChangeEvent.patch
index 6888a99771..6888a99771 100644
--- a/patches/server/0161-Add-PlayerArmorChangeEvent.patch
+++ b/patches/server/0169-Add-PlayerArmorChangeEvent.patch
diff --git a/patches/server/0162-Prevent-logins-from-being-processed-when-the-player-.patch b/patches/server/0170-Prevent-logins-from-being-processed-when-the-player-.patch
index a7bab6af89..a7bab6af89 100644
--- a/patches/server/0162-Prevent-logins-from-being-processed-when-the-player-.patch
+++ b/patches/server/0170-Prevent-logins-from-being-processed-when-the-player-.patch
diff --git a/patches/server/0163-Fix-MC-117075-TE-Unload-Lag-Spike.patch b/patches/server/0171-Fix-MC-117075-TE-Unload-Lag-Spike.patch
index d0a52d5728..d0a52d5728 100644
--- a/patches/server/0163-Fix-MC-117075-TE-Unload-Lag-Spike.patch
+++ b/patches/server/0171-Fix-MC-117075-TE-Unload-Lag-Spike.patch
diff --git a/patches/server/0164-use-CB-BlockState-implementations-for-captured-block.patch b/patches/server/0172-use-CB-BlockState-implementations-for-captured-block.patch
index 8c4fa7bc1d..8c4fa7bc1d 100644
--- a/patches/server/0164-use-CB-BlockState-implementations-for-captured-block.patch
+++ b/patches/server/0172-use-CB-BlockState-implementations-for-captured-block.patch
diff --git a/patches/server/0165-API-to-get-a-BlockState-without-a-snapshot.patch b/patches/server/0173-API-to-get-a-BlockState-without-a-snapshot.patch
index c2d8befb3f..c2d8befb3f 100644
--- a/patches/server/0165-API-to-get-a-BlockState-without-a-snapshot.patch
+++ b/patches/server/0173-API-to-get-a-BlockState-without-a-snapshot.patch
diff --git a/patches/server/0166-AsyncTabCompleteEvent.patch b/patches/server/0174-AsyncTabCompleteEvent.patch
index ab9832afe8..0172c62c70 100644
--- a/patches/server/0166-AsyncTabCompleteEvent.patch
+++ b/patches/server/0174-AsyncTabCompleteEvent.patch
@@ -16,10 +16,10 @@ Also adds isCommand and getLocation to the sync TabCompleteEvent
Co-authored-by: Aikar <[email protected]>
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-index 90b09d4fcb267dff4ab3c910948876a4408abcd1..d5861e01f7bc18a95f9287128aa829a28780e8c4 100644
+index 322ecd7671c9b1a6c359455d47ec617b7da00bdc..9d66ce602f2c71107659774d5a8a1e19071de214 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-@@ -784,27 +784,58 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
+@@ -784,12 +784,16 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
}
@@ -37,6 +37,10 @@ index 90b09d4fcb267dff4ab3c910948876a4408abcd1..d5861e01f7bc18a95f9287128aa829a2
+ server.scheduleOnMain(() -> this.disconnect(Component.translatable("disconnect.spam", new Object[0]))); // Paper
return;
}
+ // Paper start
+@@ -800,18 +804,45 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
+ }
+ // Paper end
// CraftBukkit end
+ // Paper start - async tab completion
+ TAB_COMPLETE_EXECUTOR.execute(() -> {
diff --git a/patches/server/0167-PlayerPickupExperienceEvent.patch b/patches/server/0175-PlayerPickupExperienceEvent.patch
index f59d0999a5..f59d0999a5 100644
--- a/patches/server/0167-PlayerPickupExperienceEvent.patch
+++ b/patches/server/0175-PlayerPickupExperienceEvent.patch
diff --git a/patches/server/0168-Ability-to-apply-mending-to-XP-API.patch b/patches/server/0176-Ability-to-apply-mending-to-XP-API.patch
index ff01f4a8ad..d301f387f5 100644
--- a/patches/server/0168-Ability-to-apply-mending-to-XP-API.patch
+++ b/patches/server/0176-Ability-to-apply-mending-to-XP-API.patch
@@ -10,7 +10,7 @@ of giving the player experience points.
Both an API To standalone mend, and apply mending logic to .giveExp has been added.
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
-index 4ad178d99da224927b785d586bb2057ddd73ccd8..d1271b9c31502407dfeaf8eb47b73f515bf6c0fd 100644
+index 460e237a3237d5965b2ef85d32113682ee04e52d..299f2a8c45462d8070312c98554dbcc05298c681 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -1365,7 +1365,37 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
diff --git a/patches/server/0169-PlayerNaturallySpawnCreaturesEvent.patch b/patches/server/0177-PlayerNaturallySpawnCreaturesEvent.patch
index 31e7dfcc83..e702a822a8 100644
--- a/patches/server/0169-PlayerNaturallySpawnCreaturesEvent.patch
+++ b/patches/server/0177-PlayerNaturallySpawnCreaturesEvent.patch
@@ -9,10 +9,10 @@ from triggering monster spawns on a server.
Also a highly more effecient way to blanket block spawns in a world
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
-index dd318c213742299fca1335fadf1f4465b471d7ea..cb261ab455eb2234159ba49b1c2f6c34b079973f 100644
+index e086135936e4f6c109cd09a4e4df350702b3510a..09a2680162ed9f1d82830778fea6b05a34ab382b 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
-@@ -1157,7 +1157,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -1375,7 +1375,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
chunkRange = (chunkRange > level.spigotConfig.viewDistance) ? (byte) level.spigotConfig.viewDistance : chunkRange;
chunkRange = (chunkRange > 8) ? 8 : chunkRange;
@@ -23,7 +23,7 @@ index dd318c213742299fca1335fadf1f4465b471d7ea..cb261ab455eb2234159ba49b1c2f6c34
// Spigot end
long i = chunkcoordintpair.toLong();
-@@ -1174,6 +1176,15 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -1392,6 +1394,15 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
}
entityplayer = (ServerPlayer) iterator.next();
@@ -40,10 +40,10 @@ index dd318c213742299fca1335fadf1f4465b471d7ea..cb261ab455eb2234159ba49b1c2f6c34
return true;
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
-index 86acdd910eebb8beac4536942119c9e97580ff2e..a81644df294c739b72fc638cd06a3976250caa50 100644
+index 2400212e65c72d3ce6604b3cf200db0ae7032f2a..f2775bc2c9137b7b81080f3113340923469bb46d 100644
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
-@@ -819,6 +819,15 @@ public class ServerChunkCache extends ChunkSource {
+@@ -784,6 +784,15 @@ public class ServerChunkCache extends ChunkSource {
boolean flag2 = this.level.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && !this.level.players().isEmpty(); // CraftBukkit
Collections.shuffle(list);
@@ -60,7 +60,7 @@ index 86acdd910eebb8beac4536942119c9e97580ff2e..a81644df294c739b72fc638cd06a3976
while (iterator1.hasNext()) {
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-index 8f4b8e4911d5c3bb82c9ac246c041c0eb51a3123..a9497e21c87e785631788968bc4922f6261169f9 100644
+index 5d214b7dd4f6d7feff0a1904ce6573cffd258a1c..a214916ff80885af262165d5936b8bdf2056cbed 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -1,5 +1,6 @@
@@ -70,7 +70,7 @@ index 8f4b8e4911d5c3bb82c9ac246c041c0eb51a3123..a9497e21c87e785631788968bc4922f6
import com.google.common.collect.Lists;
import com.mojang.authlib.GameProfile;
import com.mojang.datafixers.util.Either;
-@@ -245,6 +246,7 @@ public class ServerPlayer extends Player {
+@@ -246,6 +247,7 @@ public class ServerPlayer extends Player {
public Integer clientViewDistance;
public String kickLeaveMessage = null; // SPIGOT-3034: Forward leave message to PlayerQuitEvent
// CraftBukkit end
diff --git a/patches/server/0170-Add-setPlayerProfile-API-for-Skulls.patch b/patches/server/0178-Add-setPlayerProfile-API-for-Skulls.patch
index a87a829f5b..a87a829f5b 100644
--- a/patches/server/0170-Add-setPlayerProfile-API-for-Skulls.patch
+++ b/patches/server/0178-Add-setPlayerProfile-API-for-Skulls.patch
diff --git a/patches/server/0171-PreCreatureSpawnEvent.patch b/patches/server/0179-PreCreatureSpawnEvent.patch
index 82fc009561..82fc009561 100644
--- a/patches/server/0171-PreCreatureSpawnEvent.patch
+++ b/patches/server/0179-PreCreatureSpawnEvent.patch
diff --git a/patches/server/0172-Fill-Profile-Property-Events.patch b/patches/server/0180-Fill-Profile-Property-Events.patch
index 30643d081c..30643d081c 100644
--- a/patches/server/0172-Fill-Profile-Property-Events.patch
+++ b/patches/server/0180-Fill-Profile-Property-Events.patch
diff --git a/patches/server/0173-PlayerAdvancementCriterionGrantEvent.patch b/patches/server/0181-PlayerAdvancementCriterionGrantEvent.patch
index 04f350388d..04f350388d 100644
--- a/patches/server/0173-PlayerAdvancementCriterionGrantEvent.patch
+++ b/patches/server/0181-PlayerAdvancementCriterionGrantEvent.patch
diff --git a/patches/server/0174-Add-ArmorStand-Item-Meta.patch b/patches/server/0182-Add-ArmorStand-Item-Meta.patch
index 08077b5138..08077b5138 100644
--- a/patches/server/0174-Add-ArmorStand-Item-Meta.patch
+++ b/patches/server/0182-Add-ArmorStand-Item-Meta.patch
diff --git a/patches/server/0175-Extend-Player-Interact-cancellation.patch b/patches/server/0183-Extend-Player-Interact-cancellation.patch
index ef330b35a9..ef330b35a9 100644
--- a/patches/server/0175-Extend-Player-Interact-cancellation.patch
+++ b/patches/server/0183-Extend-Player-Interact-cancellation.patch
diff --git a/patches/server/0176-Tameable-getOwnerUniqueId-API.patch b/patches/server/0184-Tameable-getOwnerUniqueId-API.patch
index 7fca628e8a..7fca628e8a 100644
--- a/patches/server/0176-Tameable-getOwnerUniqueId-API.patch
+++ b/patches/server/0184-Tameable-getOwnerUniqueId-API.patch
diff --git a/patches/server/0177-Toggleable-player-crits-helps-mitigate-hacked-client.patch b/patches/server/0185-Toggleable-player-crits-helps-mitigate-hacked-client.patch
index dd76c430fe..dd76c430fe 100644
--- a/patches/server/0177-Toggleable-player-crits-helps-mitigate-hacked-client.patch
+++ b/patches/server/0185-Toggleable-player-crits-helps-mitigate-hacked-client.patch
diff --git a/patches/server/0178-Disable-Explicit-Network-Manager-Flushing.patch b/patches/server/0186-Disable-Explicit-Network-Manager-Flushing.patch
index 2afe051024..52b1cd9a42 100644
--- a/patches/server/0178-Disable-Explicit-Network-Manager-Flushing.patch
+++ b/patches/server/0186-Disable-Explicit-Network-Manager-Flushing.patch
@@ -12,7 +12,7 @@ flushing on the netty event loop, so it won't do the flush on the main thread.
Renable flushing by passing -Dpaper.explicit-flush=true
diff --git a/src/main/java/net/minecraft/network/Connection.java b/src/main/java/net/minecraft/network/Connection.java
-index b132a5ca649833043b81578a2439901eaf4c4ab5..30073d1e0c61ad94119fc0859a17b011087b6fcc 100644
+index 308b720a58320aab1e2616542bbdd2e2fc5869ee..2643c3d99c11bc6783386502c7e21293b6dfa345 100644
--- a/src/main/java/net/minecraft/network/Connection.java
+++ b/src/main/java/net/minecraft/network/Connection.java
@@ -92,6 +92,7 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
diff --git a/patches/server/0179-Implement-extended-PaperServerListPingEvent.patch b/patches/server/0187-Implement-extended-PaperServerListPingEvent.patch
index 51f0b253c4..c9dccdb403 100644
--- a/patches/server/0179-Implement-extended-PaperServerListPingEvent.patch
+++ b/patches/server/0187-Implement-extended-PaperServerListPingEvent.patch
@@ -190,7 +190,7 @@ index 67455a5ba75c9b816213e44d6872c5ddf8e27e98..23efad80934930beadf15e65781551d4
public ClientboundStatusResponsePacket(ServerStatus metadata) {
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
-index 68072a78d241bcfb54a206e7b85f038d51e26e58..bb50ca7bcbdf46d29bd749050674dc18d7e282e4 100644
+index 2d474f3bf38545d2703f1f8f80419dc774e15bf6..401b883109f0ab7b30dcdc5c0ea28fc7aa3a0822 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -2,6 +2,9 @@ package net.minecraft.server;
diff --git a/patches/server/0180-Ability-to-change-PlayerProfile-in-AsyncPreLoginEven.patch b/patches/server/0188-Ability-to-change-PlayerProfile-in-AsyncPreLoginEven.patch
index 67e2059650..67e2059650 100644
--- a/patches/server/0180-Ability-to-change-PlayerProfile-in-AsyncPreLoginEven.patch
+++ b/patches/server/0188-Ability-to-change-PlayerProfile-in-AsyncPreLoginEven.patch
diff --git a/patches/server/0181-Player.setPlayerProfile-API.patch b/patches/server/0189-Player.setPlayerProfile-API.patch
index c09ca131cd..c09ca131cd 100644
--- a/patches/server/0181-Player.setPlayerProfile-API.patch
+++ b/patches/server/0189-Player.setPlayerProfile-API.patch
diff --git a/patches/server/0182-getPlayerUniqueId-API.patch b/patches/server/0190-getPlayerUniqueId-API.patch
index 0b83ebb1eb..08d3bcf224 100644
--- a/patches/server/0182-getPlayerUniqueId-API.patch
+++ b/patches/server/0190-getPlayerUniqueId-API.patch
@@ -9,7 +9,7 @@ In Offline Mode, will return an Offline UUID
This is a more performant way to obtain a UUID for a name than loading an OfflinePlayer
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-index be5982fea6f354131e4562e2a109b4c56c77bcd9..e8becfe4cfb0b431d99a78b7726e96afbdefcf12 100644
+index 565ae5e0dc0db9aaf694003cb30e9af3ff6fc78d..94e0134dcf644ed8f2835ddceb2f1e09c1d8c6a4 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -1708,6 +1708,25 @@ public final class CraftServer implements Server {
diff --git a/patches/server/0183-Improved-Async-Task-Scheduler.patch b/patches/server/0191-Improved-Async-Task-Scheduler.patch
index b62fddc7b9..b62fddc7b9 100644
--- a/patches/server/0183-Improved-Async-Task-Scheduler.patch
+++ b/patches/server/0191-Improved-Async-Task-Scheduler.patch
diff --git a/patches/server/0184-Make-legacy-ping-handler-more-reliable.patch b/patches/server/0192-Make-legacy-ping-handler-more-reliable.patch
index 438fb37f34..438fb37f34 100644
--- a/patches/server/0184-Make-legacy-ping-handler-more-reliable.patch
+++ b/patches/server/0192-Make-legacy-ping-handler-more-reliable.patch
diff --git a/patches/server/0185-Call-PaperServerListPingEvent-for-legacy-pings.patch b/patches/server/0193-Call-PaperServerListPingEvent-for-legacy-pings.patch
index d65878827c..d65878827c 100644
--- a/patches/server/0185-Call-PaperServerListPingEvent-for-legacy-pings.patch
+++ b/patches/server/0193-Call-PaperServerListPingEvent-for-legacy-pings.patch
diff --git a/patches/server/0186-Flag-to-disable-the-channel-limit.patch b/patches/server/0194-Flag-to-disable-the-channel-limit.patch
index 60f9eed621..86fb71be62 100644
--- a/patches/server/0186-Flag-to-disable-the-channel-limit.patch
+++ b/patches/server/0194-Flag-to-disable-the-channel-limit.patch
@@ -9,7 +9,7 @@ e.g. servers which allow and support the usage of mod packs.
provide an optional flag to disable this check, at your own risk.
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
-index 32554bad10cccec164bc36063333244344c16473..c63831b9ec29ea1589cc87fbe4615f6dfddce473 100644
+index 31bcabd4c6ac3aa261c439a154ba7eb0f8caa0b8..7234e96d6d956d84fbcbcb321c1fb05906da6adb 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -167,6 +167,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
diff --git a/patches/server/0187-Add-openSign-method-to-HumanEntity.patch b/patches/server/0195-Add-openSign-method-to-HumanEntity.patch
index e3578a257b..e3578a257b 100644
--- a/patches/server/0187-Add-openSign-method-to-HumanEntity.patch
+++ b/patches/server/0195-Add-openSign-method-to-HumanEntity.patch
diff --git a/patches/server/0188-Configurable-sprint-interruption-on-attack.patch b/patches/server/0196-Configurable-sprint-interruption-on-attack.patch
index 5f5e0d01bf..5f5e0d01bf 100644
--- a/patches/server/0188-Configurable-sprint-interruption-on-attack.patch
+++ b/patches/server/0196-Configurable-sprint-interruption-on-attack.patch
diff --git a/patches/server/0189-Fix-exploit-that-allowed-colored-signs-to-be-created.patch b/patches/server/0197-Fix-exploit-that-allowed-colored-signs-to-be-created.patch
index 250b4dfb89..90921a4e32 100644
--- a/patches/server/0189-Fix-exploit-that-allowed-colored-signs-to-be-created.patch
+++ b/patches/server/0197-Fix-exploit-that-allowed-colored-signs-to-be-created.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Fix exploit that allowed colored signs to be created
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-index d5861e01f7bc18a95f9287128aa829a28780e8c4..727350fb397e9be2917fa383dc6b8abeb15670e7 100644
+index 9d66ce602f2c71107659774d5a8a1e19071de214..9b7e1b11c499fe78869487e2ba056043e1e10fff 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-@@ -3247,9 +3247,9 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
+@@ -3254,9 +3254,9 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
FilteredText filteredtext = (FilteredText) signText.get(i);
if (this.player.isTextFilteringEnabled()) {
diff --git a/patches/server/0190-EndermanEscapeEvent.patch b/patches/server/0198-EndermanEscapeEvent.patch
index 3fff4f9bad..3fff4f9bad 100644
--- a/patches/server/0190-EndermanEscapeEvent.patch
+++ b/patches/server/0198-EndermanEscapeEvent.patch
diff --git a/patches/server/0191-Enderman.teleportRandomly.patch b/patches/server/0199-Enderman.teleportRandomly.patch
index aafeea74bb..aafeea74bb 100644
--- a/patches/server/0191-Enderman.teleportRandomly.patch
+++ b/patches/server/0199-Enderman.teleportRandomly.patch
diff --git a/patches/server/0192-Block-Enderpearl-Travel-Exploit.patch b/patches/server/0200-Block-Enderpearl-Travel-Exploit.patch
index e1f3da6f02..7a04fe5676 100644
--- a/patches/server/0192-Block-Enderpearl-Travel-Exploit.patch
+++ b/patches/server/0200-Block-Enderpearl-Travel-Exploit.patch
@@ -12,10 +12,10 @@ This disables that by not saving the thrower when the chunk is unloaded.
This is mainly useful for survival servers that do not allow freeform teleporting.
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index 652c909eaa9e76c29427b7220adf9fe4947c2e84..c0a53e0effda295b9a4a798a0c7b29bd6ed9e435 100644
+index 4a6c03f421d81b694ca8670994c9322d4425922b..3162951ff50d65d0d2fcf55d0606208dc28b9146 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
-@@ -2073,6 +2073,12 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -2149,6 +2149,12 @@ public class ServerLevel extends Level implements WorldGenLevel {
public void onTickingEnd(Entity entity) {
ServerLevel.this.entityTickList.remove(entity);
diff --git a/patches/server/0193-Expand-World.spawnParticle-API-and-add-Builder.patch b/patches/server/0201-Expand-World.spawnParticle-API-and-add-Builder.patch
index 18756fe570..8fc08a8246 100644
--- a/patches/server/0193-Expand-World.spawnParticle-API-and-add-Builder.patch
+++ b/patches/server/0201-Expand-World.spawnParticle-API-and-add-Builder.patch
@@ -10,10 +10,10 @@ Adds an option to control the force mode of the particle.
This adds a new Builder API which is much friendlier to use.
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index c0a53e0effda295b9a4a798a0c7b29bd6ed9e435..3d3926a14229d922fb7b7e76c9babb031bf7d9ab 100644
+index 3162951ff50d65d0d2fcf55d0606208dc28b9146..3cd979a88be53fb2f5b785fa98d7b5c0c705e1f9 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
-@@ -1486,12 +1486,17 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -1562,12 +1562,17 @@ public class ServerLevel extends Level implements WorldGenLevel {
}
public <T extends ParticleOptions> int sendParticles(ServerPlayer sender, T t0, double d0, double d1, double d2, int i, double d3, double d4, double d5, double d6, boolean force) {
@@ -34,10 +34,10 @@ index c0a53e0effda295b9a4a798a0c7b29bd6ed9e435..3d3926a14229d922fb7b7e76c9babb03
if (this.sendParticles(entityplayer, force, d0, d1, d2, packetplayoutworldparticles)) { // CraftBukkit
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-index 40dd3913ac630899206a506ea9dfc58de634f391..d7502ef49d15b13d6f38da5bfc183de47962ecba 100644
+index b2e693b6a799568c6196c1f805f0153ea69b8bd2..0654af81e20a75c3b0b8e11e824f680f3eb01626 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-@@ -1820,11 +1820,17 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+@@ -1819,11 +1819,17 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@Override
public <T> void spawnParticle(Particle particle, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ, double extra, T data, boolean force) {
diff --git a/patches/server/0194-Prevent-Frosted-Ice-from-loading-holding-chunks.patch b/patches/server/0202-Prevent-Frosted-Ice-from-loading-holding-chunks.patch
index b9c45b572d..b9c45b572d 100644
--- a/patches/server/0194-Prevent-Frosted-Ice-from-loading-holding-chunks.patch
+++ b/patches/server/0202-Prevent-Frosted-Ice-from-loading-holding-chunks.patch
diff --git a/patches/server/0195-EndermanAttackPlayerEvent.patch b/patches/server/0203-EndermanAttackPlayerEvent.patch
index 6a1eef464f..6a1eef464f 100644
--- a/patches/server/0195-EndermanAttackPlayerEvent.patch
+++ b/patches/server/0203-EndermanAttackPlayerEvent.patch
diff --git a/patches/server/0196-WitchConsumePotionEvent.patch b/patches/server/0204-WitchConsumePotionEvent.patch
index f054a8dd3c..f054a8dd3c 100644
--- a/patches/server/0196-WitchConsumePotionEvent.patch
+++ b/patches/server/0204-WitchConsumePotionEvent.patch
diff --git a/patches/server/0197-WitchThrowPotionEvent.patch b/patches/server/0205-WitchThrowPotionEvent.patch
index 86ba404bc1..86ba404bc1 100644
--- a/patches/server/0197-WitchThrowPotionEvent.patch
+++ b/patches/server/0205-WitchThrowPotionEvent.patch
diff --git a/patches/server/0198-Allow-spawning-Item-entities-with-World.spawnEntity.patch b/patches/server/0206-Allow-spawning-Item-entities-with-World.spawnEntity.patch
index 9bfc81d04d..9bfc81d04d 100644
--- a/patches/server/0198-Allow-spawning-Item-entities-with-World.spawnEntity.patch
+++ b/patches/server/0206-Allow-spawning-Item-entities-with-World.spawnEntity.patch
diff --git a/patches/server/0199-WitchReadyPotionEvent.patch b/patches/server/0207-WitchReadyPotionEvent.patch
index 99ac9dce10..99ac9dce10 100644
--- a/patches/server/0199-WitchReadyPotionEvent.patch
+++ b/patches/server/0207-WitchReadyPotionEvent.patch
diff --git a/patches/server/0200-ItemStack-getMaxItemUseDuration.patch b/patches/server/0208-ItemStack-getMaxItemUseDuration.patch
index 96e27516fa..96e27516fa 100644
--- a/patches/server/0200-ItemStack-getMaxItemUseDuration.patch
+++ b/patches/server/0208-ItemStack-getMaxItemUseDuration.patch
diff --git a/patches/server/0201-Implement-EntityTeleportEndGatewayEvent.patch b/patches/server/0209-Implement-EntityTeleportEndGatewayEvent.patch
index b1a4699bbc..b1a4699bbc 100644
--- a/patches/server/0201-Implement-EntityTeleportEndGatewayEvent.patch
+++ b/patches/server/0209-Implement-EntityTeleportEndGatewayEvent.patch
diff --git a/patches/server/0202-Unset-Ignited-flag-on-cancel-of-Explosion-Event.patch b/patches/server/0210-Unset-Ignited-flag-on-cancel-of-Explosion-Event.patch
index 6f7b7cd31b..6f7b7cd31b 100644
--- a/patches/server/0202-Unset-Ignited-flag-on-cancel-of-Explosion-Event.patch
+++ b/patches/server/0210-Unset-Ignited-flag-on-cancel-of-Explosion-Event.patch
diff --git a/patches/server/0203-Fix-CraftEntity-hashCode.patch b/patches/server/0211-Fix-CraftEntity-hashCode.patch
index 99f647d7b3..26e3d9d00b 100644
--- a/patches/server/0203-Fix-CraftEntity-hashCode.patch
+++ b/patches/server/0211-Fix-CraftEntity-hashCode.patch
@@ -21,7 +21,7 @@ check is essentially the same as this.getHandle() == other.getHandle()
However, replaced it too to make it clearer of intent.
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
-index 41753b72ac6fdf0314d60dbe1ffb60e79b3e4af8..e6b75dfa1a59c9f1f6afde7b4538abf8d51b7261 100644
+index 5a8e31d3e1078559f17151a8f9a9cbaec58b1942..f70cc39d7fdd9308fd328007fcadbaab1780ad5f 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
@@ -807,14 +807,15 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
diff --git a/patches/server/0204-Configurable-Alternative-LootPool-Luck-Formula.patch b/patches/server/0212-Configurable-Alternative-LootPool-Luck-Formula.patch
index 40dce864c6..40dce864c6 100644
--- a/patches/server/0204-Configurable-Alternative-LootPool-Luck-Formula.patch
+++ b/patches/server/0212-Configurable-Alternative-LootPool-Luck-Formula.patch
diff --git a/patches/server/0205-Print-Error-details-when-failing-to-save-player-data.patch b/patches/server/0213-Print-Error-details-when-failing-to-save-player-data.patch
index 1fa6aa9aac..1fa6aa9aac 100644
--- a/patches/server/0205-Print-Error-details-when-failing-to-save-player-data.patch
+++ b/patches/server/0213-Print-Error-details-when-failing-to-save-player-data.patch
diff --git a/patches/server/0206-Make-shield-blocking-delay-configurable.patch b/patches/server/0214-Make-shield-blocking-delay-configurable.patch
index 331bfc40f7..331bfc40f7 100644
--- a/patches/server/0206-Make-shield-blocking-delay-configurable.patch
+++ b/patches/server/0214-Make-shield-blocking-delay-configurable.patch
diff --git a/patches/server/0207-Improve-EntityShootBowEvent.patch b/patches/server/0215-Improve-EntityShootBowEvent.patch
index 80a633b156..80a633b156 100644
--- a/patches/server/0207-Improve-EntityShootBowEvent.patch
+++ b/patches/server/0215-Improve-EntityShootBowEvent.patch
diff --git a/patches/server/0208-PlayerReadyArrowEvent.patch b/patches/server/0216-PlayerReadyArrowEvent.patch
index ccaaa2610b..ccaaa2610b 100644
--- a/patches/server/0208-PlayerReadyArrowEvent.patch
+++ b/patches/server/0216-PlayerReadyArrowEvent.patch
diff --git a/patches/server/0209-Implement-EntityKnockbackByEntityEvent.patch b/patches/server/0217-Implement-EntityKnockbackByEntityEvent.patch
index 0cb31474ad..0cb31474ad 100644
--- a/patches/server/0209-Implement-EntityKnockbackByEntityEvent.patch
+++ b/patches/server/0217-Implement-EntityKnockbackByEntityEvent.patch
diff --git a/patches/server/0210-Expand-Explosions-API.patch b/patches/server/0218-Expand-Explosions-API.patch
index 65c44e48dd..890d08a4f6 100644
--- a/patches/server/0210-Expand-Explosions-API.patch
+++ b/patches/server/0218-Expand-Explosions-API.patch
@@ -6,10 +6,10 @@ Subject: [PATCH] Expand Explosions API
Add Entity as a Source capability, and add more API choices, and on Location.
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-index d7502ef49d15b13d6f38da5bfc183de47962ecba..7a89e5c37699762def7501754e0376f04818c6ed 100644
+index 0654af81e20a75c3b0b8e11e824f680f3eb01626..3347e42bf45be9d640ee267bc2e0df8f241ce45c 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-@@ -714,6 +714,12 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+@@ -713,6 +713,12 @@ public class CraftWorld extends CraftRegionAccessor implements World {
public boolean createExplosion(double x, double y, double z, float power, boolean setFire, boolean breakBlocks, Entity source) {
return !this.world.explode(source == null ? null : ((CraftEntity) source).getHandle(), x, y, z, power, setFire, breakBlocks ? Explosion.BlockInteraction.BREAK : Explosion.BlockInteraction.NONE).wasCanceled;
}
diff --git a/patches/server/0211-LivingEntity-Hand-Raised-Item-Use-API.patch b/patches/server/0219-LivingEntity-Hand-Raised-Item-Use-API.patch
index b8c1582431..b8c1582431 100644
--- a/patches/server/0211-LivingEntity-Hand-Raised-Item-Use-API.patch
+++ b/patches/server/0219-LivingEntity-Hand-Raised-Item-Use-API.patch
diff --git a/patches/server/0212-RangedEntity-API.patch b/patches/server/0220-RangedEntity-API.patch
index 94da937638..94da937638 100644
--- a/patches/server/0212-RangedEntity-API.patch
+++ b/patches/server/0220-RangedEntity-API.patch
diff --git a/patches/server/0213-Add-config-to-disable-ender-dragon-legacy-check.patch b/patches/server/0221-Add-config-to-disable-ender-dragon-legacy-check.patch
index e2cb389ce5..e2cb389ce5 100644
--- a/patches/server/0213-Add-config-to-disable-ender-dragon-legacy-check.patch
+++ b/patches/server/0221-Add-config-to-disable-ender-dragon-legacy-check.patch
diff --git a/patches/server/0214-Implement-World.getEntity-UUID-API.patch b/patches/server/0222-Implement-World.getEntity-UUID-API.patch
index 5c3dc04177..49d3106298 100644
--- a/patches/server/0214-Implement-World.getEntity-UUID-API.patch
+++ b/patches/server/0222-Implement-World.getEntity-UUID-API.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Implement World.getEntity(UUID) API
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-index 7a89e5c37699762def7501754e0376f04818c6ed..124c1b07067a889ffeb5b9994b0b3be4d3e64540 100644
+index 3347e42bf45be9d640ee267bc2e0df8f241ce45c..ff842f952d744a13eb563407edc21d03d43ddd66 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-@@ -1048,6 +1048,15 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+@@ -1047,6 +1047,15 @@ public class CraftWorld extends CraftRegionAccessor implements World {
return list;
}
diff --git a/patches/server/0215-InventoryCloseEvent-Reason-API.patch b/patches/server/0223-InventoryCloseEvent-Reason-API.patch
index d62c930502..c4c5b1b14e 100644
--- a/patches/server/0215-InventoryCloseEvent-Reason-API.patch
+++ b/patches/server/0223-InventoryCloseEvent-Reason-API.patch
@@ -7,10 +7,10 @@ Allows you to determine why an inventory was closed, enabling plugin developers
to "confirm" things based on if it was player triggered close or not.
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index 0b1676f71e8da09af3cc0db1c6c17059a6bcf60c..45038c25904d919e0b69deaecdc09272df05bab4 100644
+index 3cd979a88be53fb2f5b785fa98d7b5c0c705e1f9..e13fa5d2ed02b5fe8f9f9d124d15dd5374a7f472 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
-@@ -1159,7 +1159,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -1235,7 +1235,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
for (net.minecraft.world.level.block.entity.BlockEntity tileentity : chunk.getBlockEntities().values()) {
if (tileentity instanceof net.minecraft.world.Container) {
for (org.bukkit.entity.HumanEntity h : Lists.newArrayList(((net.minecraft.world.Container) tileentity).getViewers())) {
@@ -19,7 +19,7 @@ index 0b1676f71e8da09af3cc0db1c6c17059a6bcf60c..45038c25904d919e0b69deaecdc09272
}
}
}
-@@ -2163,7 +2163,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -2239,7 +2239,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
// Spigot Start
if (entity.getBukkitEntity() instanceof org.bukkit.inventory.InventoryHolder && (!(entity instanceof ServerPlayer) || entity.getRemovalReason() != Entity.RemovalReason.KILLED)) { // SPIGOT-6876: closeInventory clears death message
for (org.bukkit.entity.HumanEntity h : Lists.newArrayList(((org.bukkit.inventory.InventoryHolder) entity.getBukkitEntity()).getInventory().getViewers())) {
@@ -29,10 +29,10 @@ index 0b1676f71e8da09af3cc0db1c6c17059a6bcf60c..45038c25904d919e0b69deaecdc09272
}
// Spigot End
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-index 4eb69b62b4c3f568cad83fdc4b19cbde2c588be7..35a6dd9cfed631f66e31c71911433ec880711905 100644
+index a214916ff80885af262165d5936b8bdf2056cbed..4b9af6ef008a297438bfc583025d235d07d9b780 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-@@ -610,7 +610,7 @@ public class ServerPlayer extends Player {
+@@ -626,7 +626,7 @@ public class ServerPlayer extends Player {
}
// Paper end
if (!this.level.isClientSide && !this.containerMenu.stillValid(this)) {
@@ -41,7 +41,7 @@ index 4eb69b62b4c3f568cad83fdc4b19cbde2c588be7..35a6dd9cfed631f66e31c71911433ec8
this.containerMenu = this.inventoryMenu;
}
-@@ -803,7 +803,7 @@ public class ServerPlayer extends Player {
+@@ -819,7 +819,7 @@ public class ServerPlayer extends Player {
// SPIGOT-943 - only call if they have an inventory open
if (this.containerMenu != this.inventoryMenu) {
@@ -50,7 +50,7 @@ index 4eb69b62b4c3f568cad83fdc4b19cbde2c588be7..35a6dd9cfed631f66e31c71911433ec8
}
net.kyori.adventure.text.Component deathMessage = event.deathMessage() != null ? event.deathMessage() : net.kyori.adventure.text.Component.empty(); // Paper - Adventure
-@@ -1441,7 +1441,7 @@ public class ServerPlayer extends Player {
+@@ -1457,7 +1457,7 @@ public class ServerPlayer extends Player {
}
// CraftBukkit end
if (this.containerMenu != this.inventoryMenu) {
@@ -59,7 +59,7 @@ index 4eb69b62b4c3f568cad83fdc4b19cbde2c588be7..35a6dd9cfed631f66e31c71911433ec8
}
// this.nextContainerCounter(); // CraftBukkit - moved up
-@@ -1469,7 +1469,13 @@ public class ServerPlayer extends Player {
+@@ -1485,7 +1485,13 @@ public class ServerPlayer extends Player {
@Override
public void closeContainer() {
@@ -75,7 +75,7 @@ index 4eb69b62b4c3f568cad83fdc4b19cbde2c588be7..35a6dd9cfed631f66e31c71911433ec8
this.doCloseContainer();
}
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-index 727350fb397e9be2917fa383dc6b8abeb15670e7..f7552186d8a5144c23d495bdc6a450e55d8f40d1 100644
+index 9b7e1b11c499fe78869487e2ba056043e1e10fff..68d46505791e0c29b22fa266c70c996b0f10713c 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -219,6 +219,7 @@ import org.bukkit.event.inventory.ClickType;
@@ -86,7 +86,7 @@ index 727350fb397e9be2917fa383dc6b8abeb15670e7..f7552186d8a5144c23d495bdc6a450e5
import org.bukkit.event.inventory.InventoryCreativeEvent;
import org.bukkit.event.inventory.InventoryType.SlotType;
import org.bukkit.event.inventory.SmithItemEvent;
-@@ -2773,10 +2774,15 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
+@@ -2780,10 +2781,15 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
@Override
public void handleContainerClose(ServerboundContainerClosePacket packet) {
@@ -104,10 +104,10 @@ index 727350fb397e9be2917fa383dc6b8abeb15670e7..f7552186d8a5144c23d495bdc6a450e5
this.player.doCloseContainer();
}
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
-index 8d46d3a77fa9717075dcfef44a42948c2f274182..04a41c3ab90fcdfaedb1646137fb5dde12a9331b 100644
+index bf5cfdae384e44b3cef5d7edb69a559803f583a4..0629b2df97119e242d10e41a707ba47894ce6d69 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
-@@ -507,7 +507,7 @@ public abstract class PlayerList {
+@@ -508,7 +508,7 @@ public abstract class PlayerList {
// CraftBukkit start - Quitting must be before we do final save of data, in case plugins need to modify it
// See SPIGOT-5799, SPIGOT-6145
if (entityplayer.containerMenu != entityplayer.inventoryMenu) {
diff --git a/patches/server/0216-Vex-get-setSummoner-API.patch b/patches/server/0224-Vex-get-setSummoner-API.patch
index b39cab89d2..b39cab89d2 100644
--- a/patches/server/0216-Vex-get-setSummoner-API.patch
+++ b/patches/server/0224-Vex-get-setSummoner-API.patch
diff --git a/patches/server/0217-Refresh-player-inventory-when-cancelling-PlayerInter.patch b/patches/server/0225-Refresh-player-inventory-when-cancelling-PlayerInter.patch
index f381a0ed77..882f5bc09a 100644
--- a/patches/server/0217-Refresh-player-inventory-when-cancelling-PlayerInter.patch
+++ b/patches/server/0225-Refresh-player-inventory-when-cancelling-PlayerInter.patch
@@ -16,10 +16,10 @@ Refresh the player inventory when PlayerInteractEntityEvent is
cancelled to avoid this problem.
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-index f7552186d8a5144c23d495bdc6a450e55d8f40d1..abd3899c41c8c8be53cab04d946d15e621369d9a 100644
+index 68d46505791e0c29b22fa266c70c996b0f10713c..38d9abe5f34c17b66c8eaf40fac87fc16786f095 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-@@ -2658,6 +2658,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
+@@ -2665,6 +2665,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
}
if (event.isCancelled()) {
diff --git a/patches/server/0218-Use-AsyncAppender-to-keep-logging-IO-off-main-thread.patch b/patches/server/0226-Use-AsyncAppender-to-keep-logging-IO-off-main-thread.patch
index 93bf1ca349..93bf1ca349 100644
--- a/patches/server/0218-Use-AsyncAppender-to-keep-logging-IO-off-main-thread.patch
+++ b/patches/server/0226-Use-AsyncAppender-to-keep-logging-IO-off-main-thread.patch
diff --git a/patches/server/0219-add-more-information-to-Entity.toString.patch b/patches/server/0227-add-more-information-to-Entity.toString.patch
index 2fc7c9e63f..b441179e4f 100644
--- a/patches/server/0219-add-more-information-to-Entity.toString.patch
+++ b/patches/server/0227-add-more-information-to-Entity.toString.patch
@@ -6,7 +6,7 @@ Subject: [PATCH] add more information to Entity.toString()
UUID, ticks lived, valid, dead
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
-index 2e7b3de046bace7c4c275654a0f1e9066790db0c..3ef34b1da06eac4b160e56966c2e441cf9fa2f89 100644
+index 81fd2e443de0b85b340b48e66bc5fb0acad5d60a..dd00721df47c84629cc5399dd558c531f6cea1cc 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -2902,7 +2902,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
diff --git a/patches/server/0220-Add-CraftMagicNumbers.isSupportedApiVersion.patch b/patches/server/0228-Add-CraftMagicNumbers.isSupportedApiVersion.patch
index 2d9be80ee1..c90009e730 100644
--- a/patches/server/0220-Add-CraftMagicNumbers.isSupportedApiVersion.patch
+++ b/patches/server/0228-Add-CraftMagicNumbers.isSupportedApiVersion.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] Add CraftMagicNumbers.isSupportedApiVersion()
diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
-index e6ffdbeb55eaeb8c2ea7c01a5206242f54756f2b..bd8f051496aae64d317ae0cff9f21662f016c62b 100644
+index df814f6bd071cef89cd4275e11aadc8311abd0f4..5893b764d3fceccef8704f1f90a5c826d6012166 100644
--- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
@@ -426,6 +426,11 @@ public final class CraftMagicNumbers implements UnsafeValues {
diff --git a/patches/server/0221-EnderDragon-Events.patch b/patches/server/0229-EnderDragon-Events.patch
index 6368f8e07f..6368f8e07f 100644
--- a/patches/server/0221-EnderDragon-Events.patch
+++ b/patches/server/0229-EnderDragon-Events.patch
diff --git a/patches/server/0222-PlayerElytraBoostEvent.patch b/patches/server/0230-PlayerElytraBoostEvent.patch
index fde7853fad..fde7853fad 100644
--- a/patches/server/0222-PlayerElytraBoostEvent.patch
+++ b/patches/server/0230-PlayerElytraBoostEvent.patch
diff --git a/patches/server/0223-PlayerLaunchProjectileEvent.patch b/patches/server/0231-PlayerLaunchProjectileEvent.patch
index d732a1386e..d732a1386e 100644
--- a/patches/server/0223-PlayerLaunchProjectileEvent.patch
+++ b/patches/server/0231-PlayerLaunchProjectileEvent.patch
diff --git a/patches/server/0224-Improve-BlockPosition-inlining.patch b/patches/server/0232-Improve-BlockPosition-inlining.patch
index c8ba260207..c8ba260207 100644
--- a/patches/server/0224-Improve-BlockPosition-inlining.patch
+++ b/patches/server/0232-Improve-BlockPosition-inlining.patch
diff --git a/patches/server/0225-Option-to-prevent-armor-stands-from-doing-entity-loo.patch b/patches/server/0233-Option-to-prevent-armor-stands-from-doing-entity-loo.patch
index cdc5540281..cdc5540281 100644
--- a/patches/server/0225-Option-to-prevent-armor-stands-from-doing-entity-loo.patch
+++ b/patches/server/0233-Option-to-prevent-armor-stands-from-doing-entity-loo.patch
diff --git a/patches/server/0226-Vanished-players-don-t-have-rights.patch b/patches/server/0234-Vanished-players-don-t-have-rights.patch
index 07339f4496..07339f4496 100644
--- a/patches/server/0226-Vanished-players-don-t-have-rights.patch
+++ b/patches/server/0234-Vanished-players-don-t-have-rights.patch
diff --git a/patches/server/0227-Allow-disabling-armour-stand-ticking.patch b/patches/server/0235-Allow-disabling-armour-stand-ticking.patch
index 8c8a8d1532..8c8a8d1532 100644
--- a/patches/server/0227-Allow-disabling-armour-stand-ticking.patch
+++ b/patches/server/0235-Allow-disabling-armour-stand-ticking.patch
diff --git a/patches/server/0228-SkeletonHorse-Additions.patch b/patches/server/0236-SkeletonHorse-Additions.patch
index 587c1eae7f..587c1eae7f 100644
--- a/patches/server/0228-SkeletonHorse-Additions.patch
+++ b/patches/server/0236-SkeletonHorse-Additions.patch
diff --git a/patches/server/0229-Don-t-call-getItemMeta-on-hasItemMeta.patch b/patches/server/0237-Don-t-call-getItemMeta-on-hasItemMeta.patch
index bc8d5e861e..bc8d5e861e 100644
--- a/patches/server/0229-Don-t-call-getItemMeta-on-hasItemMeta.patch
+++ b/patches/server/0237-Don-t-call-getItemMeta-on-hasItemMeta.patch
diff --git a/patches/server/0230-Implement-Expanded-ArmorStand-API.patch b/patches/server/0238-Implement-Expanded-ArmorStand-API.patch
index ace889510d..ace889510d 100644
--- a/patches/server/0230-Implement-Expanded-ArmorStand-API.patch
+++ b/patches/server/0238-Implement-Expanded-ArmorStand-API.patch
diff --git a/patches/server/0231-AnvilDamageEvent.patch b/patches/server/0239-AnvilDamageEvent.patch
index c20941bfde..c20941bfde 100644
--- a/patches/server/0231-AnvilDamageEvent.patch
+++ b/patches/server/0239-AnvilDamageEvent.patch
diff --git a/patches/server/0232-Add-hand-to-bucket-events.patch b/patches/server/0240-Add-hand-to-bucket-events.patch
index b514aa8def..b514aa8def 100644
--- a/patches/server/0232-Add-hand-to-bucket-events.patch
+++ b/patches/server/0240-Add-hand-to-bucket-events.patch
diff --git a/patches/server/0233-Add-TNTPrimeEvent.patch b/patches/server/0241-Add-TNTPrimeEvent.patch
index ee73234df5..ee73234df5 100644
--- a/patches/server/0233-Add-TNTPrimeEvent.patch
+++ b/patches/server/0241-Add-TNTPrimeEvent.patch
diff --git a/patches/server/0234-Break-up-and-make-tab-spam-limits-configurable.patch b/patches/server/0242-Break-up-and-make-tab-spam-limits-configurable.patch
index d6f929806f..f414623882 100644
--- a/patches/server/0234-Break-up-and-make-tab-spam-limits-configurable.patch
+++ b/patches/server/0242-Break-up-and-make-tab-spam-limits-configurable.patch
@@ -22,7 +22,7 @@ to take the burden of this into their own hand without having to rely on
plugins doing unsafe things.
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-index abd3899c41c8c8be53cab04d946d15e621369d9a..0bac1fa4637d7132871b8f57b0431724bc9aa8c1 100644
+index 38d9abe5f34c17b66c8eaf40fac87fc16786f095..d991354d65305ab7d02666f7c3362e4136c3f6af 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -262,6 +262,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
diff --git a/patches/server/0235-MC-135506-Experience-should-save-as-Integers.patch b/patches/server/0243-MC-135506-Experience-should-save-as-Integers.patch
index 8248a48e4a..8248a48e4a 100644
--- a/patches/server/0235-MC-135506-Experience-should-save-as-Integers.patch
+++ b/patches/server/0243-MC-135506-Experience-should-save-as-Integers.patch
diff --git a/patches/server/0236-Remove-unnecessary-itemmeta-handling.patch b/patches/server/0244-Remove-unnecessary-itemmeta-handling.patch
index 88a7a7fd0c..88a7a7fd0c 100644
--- a/patches/server/0236-Remove-unnecessary-itemmeta-handling.patch
+++ b/patches/server/0244-Remove-unnecessary-itemmeta-handling.patch
diff --git a/patches/server/0237-Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch b/patches/server/0245-Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch
index db9ee43cf3..6bd58ca835 100644
--- a/patches/server/0237-Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch
+++ b/patches/server/0245-Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch
@@ -8,10 +8,10 @@ Add -Ddebug.entities=true to your JVM flags to gain more information
1.17: Needs to be reworked for new entity storage system
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
-index cb261ab455eb2234159ba49b1c2f6c34b079973f..7793d6c254c418847d3b5b65e5232bf8192b561b 100644
+index 09a2680162ed9f1d82830778fea6b05a34ab382b..8d0f7fb501aa5caa36b7dd273a8a7c7f959759cb 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
-@@ -1396,6 +1396,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -1614,6 +1614,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
} else {
ChunkMap.TrackedEntity playerchunkmap_entitytracker = new ChunkMap.TrackedEntity(entity, i, j, entitytypes.trackDeltas());
@@ -19,7 +19,7 @@ index cb261ab455eb2234159ba49b1c2f6c34b079973f..7793d6c254c418847d3b5b65e5232bf8
this.entityMap.put(entity.getId(), playerchunkmap_entitytracker);
playerchunkmap_entitytracker.updatePlayers(this.level.players());
if (entity instanceof ServerPlayer) {
-@@ -1438,7 +1439,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -1656,7 +1657,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
if (playerchunkmap_entitytracker1 != null) {
playerchunkmap_entitytracker1.broadcastRemoved();
}
@@ -29,7 +29,7 @@ index cb261ab455eb2234159ba49b1c2f6c34b079973f..7793d6c254c418847d3b5b65e5232bf8
protected void tick() {
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index 5029436157fe7279a2a583f06b7d02a0413d2178..cfaa5a5df9ae2fb0147d66b41de91e6b771b769c 100644
+index e13fa5d2ed02b5fe8f9f9d124d15dd5374a7f472..377ebed70c5008d69701bd919f22ad4506dd129c 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -216,6 +216,9 @@ public class ServerLevel extends Level implements WorldGenLevel {
@@ -42,7 +42,7 @@ index 5029436157fe7279a2a583f06b7d02a0413d2178..cfaa5a5df9ae2fb0147d66b41de91e6b
@Override public LevelChunk getChunkIfLoaded(int x, int z) { // Paper - this was added in world too but keeping here for NMS ABI
return this.chunkSource.getChunk(x, z, false);
-@@ -1121,7 +1124,28 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -1197,7 +1200,28 @@ public class ServerLevel extends Level implements WorldGenLevel {
// CraftBukkit start
private boolean addEntity(Entity entity, CreatureSpawnEvent.SpawnReason spawnReason) {
org.spigotmc.AsyncCatcher.catchOp("entity add"); // Spigot
@@ -72,7 +72,7 @@ index 5029436157fe7279a2a583f06b7d02a0413d2178..cfaa5a5df9ae2fb0147d66b41de91e6b
return false;
} else {
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
-index 3ef34b1da06eac4b160e56966c2e441cf9fa2f89..ed79a9d5a822370a9a285e58773669a00b159054 100644
+index dd00721df47c84629cc5399dd558c531f6cea1cc..29c71c951ce7114dfb24f0c99c3bf8c2a6f6144f 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -235,6 +235,8 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
diff --git a/patches/server/0238-Add-Early-Warning-Feature-to-WatchDog.patch b/patches/server/0246-Add-Early-Warning-Feature-to-WatchDog.patch
index beb82f3bbd..7cac64f958 100644
--- a/patches/server/0238-Add-Early-Warning-Feature-to-WatchDog.patch
+++ b/patches/server/0246-Add-Early-Warning-Feature-to-WatchDog.patch
@@ -9,7 +9,7 @@ thread dumps at an interval until the point of crash.
This will help diagnose what was going on in that time before the crash.
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
-index e7cd33be3c74ca79f9f0fecea010081b24a14417..ac36f50fd721b0087248bfb733fe4ea78a115778 100644
+index 401b883109f0ab7b30dcdc5c0ea28fc7aa3a0822..802b7767dd0878cf6d2e52bea74d5664f7d0664f 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -1061,6 +1061,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -33,7 +33,7 @@ index 9411e5664c0067f976018fe19b1e74032f24bd5f..1e7bccbf551043d822edb1983fa039a4
com.destroystokyo.paper.Metrics.PaperMetrics.startMetrics();
com.destroystokyo.paper.VersionHistoryManager.INSTANCE.getClass(); // load version history now
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-index e8becfe4cfb0b431d99a78b7726e96afbdefcf12..71415a6ca5bd61fa5652006ed748048d65a0502b 100644
+index 94e0134dcf644ed8f2835ddceb2f1e09c1d8c6a4..11d7f2d41da52cd0fdb96310153cd6d5547a6b8f 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -911,6 +911,7 @@ public final class CraftServer implements Server {
@@ -66,7 +66,7 @@ index 645643d102118ad4916a152abfb9ab0d02751e11..edc5f195cc3de8885b839469656650ba
public static boolean bungee;
diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/spigotmc/WatchdogThread.java
-index 6e1fa4f0616ccfd258acd1b4f5b08fc0ad4c9529..06efdd7aa6d35a670e81c4f303618a7ba301396a 100644
+index bd515ddc88f71a31531418c43725e438de100fcd..e62f085de1678568d422ef0eda5b9bfbd8b4d556 100644
--- a/src/main/java/org/spigotmc/WatchdogThread.java
+++ b/src/main/java/org/spigotmc/WatchdogThread.java
@@ -14,6 +14,10 @@ public class WatchdogThread extends Thread
@@ -110,7 +110,7 @@ index 6e1fa4f0616ccfd258acd1b4f5b08fc0ad4c9529..06efdd7aa6d35a670e81c4f303618a7b
log.log( Level.SEVERE, "------------------------------" );
log.log( Level.SEVERE, "The server has stopped responding! This is (probably) not a Paper bug." ); // Paper
log.log( Level.SEVERE, "If you see a plugin in the Server thread dump below, then please report it to that author" );
-@@ -93,29 +108,45 @@ public class WatchdogThread extends Thread
+@@ -93,30 +108,46 @@ public class WatchdogThread extends Thread
}
}
// Paper end
@@ -122,6 +122,7 @@ index 6e1fa4f0616ccfd258acd1b4f5b08fc0ad4c9529..06efdd7aa6d35a670e81c4f303618a7b
+ // Paper end - Different message for short timeout
log.log( Level.SEVERE, "------------------------------" );
log.log( Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Paper!):" ); // Paper
+ com.destroystokyo.paper.io.chunk.ChunkTaskManager.dumpAllChunkLoadInfo(); // Paper
WatchdogThread.dumpThread( ManagementFactory.getThreadMXBean().getThreadInfo( MinecraftServer.getServer().serverThread.getId(), Integer.MAX_VALUE ), log );
log.log( Level.SEVERE, "------------------------------" );
//
diff --git a/patches/server/0239-Use-ConcurrentHashMap-in-JsonList.patch b/patches/server/0247-Use-ConcurrentHashMap-in-JsonList.patch
index 15c2ad2fd9..792b86d193 100644
--- a/patches/server/0239-Use-ConcurrentHashMap-in-JsonList.patch
+++ b/patches/server/0247-Use-ConcurrentHashMap-in-JsonList.patch
@@ -23,10 +23,10 @@ Modified isEmpty to use the isEmpty() method instead of the slightly confusing s
The point of this is readability, but does have a side-benefit of a small microptimization
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
-index 2ad88d72a9d14c7e73a824544a1ebcb6bb74a127..734a7b101e5ac9ac4ceb0ba3cb74b94bf2c18683 100644
+index 0629b2df97119e242d10e41a707ba47894ce6d69..c974120dda3bac8a4a74c4b4d8ddcfb802f792dc 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
-@@ -623,7 +623,7 @@ public abstract class PlayerList {
+@@ -624,7 +624,7 @@ public abstract class PlayerList {
} else if (!this.isWhiteListed(gameprofile, event)) { // Paper
//ichatmutablecomponent = Component.translatable("multiplayer.disconnect.not_whitelisted"); // Paper
//event.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(org.spigotmc.SpigotConfig.whitelistMessage)); // Spigot // Paper - Adventure - moved to isWhitelisted
diff --git a/patches/server/0240-Use-a-Queue-for-Queueing-Commands.patch b/patches/server/0248-Use-a-Queue-for-Queueing-Commands.patch
index 3bb60868e3..3bb60868e3 100644
--- a/patches/server/0240-Use-a-Queue-for-Queueing-Commands.patch
+++ b/patches/server/0248-Use-a-Queue-for-Queueing-Commands.patch
diff --git a/patches/server/0241-Ability-to-get-Tile-Entities-from-a-chunk-without-sn.patch b/patches/server/0249-Ability-to-get-Tile-Entities-from-a-chunk-without-sn.patch
index 9917cfd41d..9917cfd41d 100644
--- a/patches/server/0241-Ability-to-get-Tile-Entities-from-a-chunk-without-sn.patch
+++ b/patches/server/0249-Ability-to-get-Tile-Entities-from-a-chunk-without-sn.patch
diff --git a/patches/server/0242-Optimize-BlockPosition-helper-methods.patch b/patches/server/0250-Optimize-BlockPosition-helper-methods.patch
index 3fe5135a6b..3fe5135a6b 100644
--- a/patches/server/0242-Optimize-BlockPosition-helper-methods.patch
+++ b/patches/server/0250-Optimize-BlockPosition-helper-methods.patch
diff --git a/patches/server/0243-Restore-vanilla-default-mob-spawn-range-and-water-an.patch b/patches/server/0251-Restore-vanilla-default-mob-spawn-range-and-water-an.patch
index e10d949eea..e10d949eea 100644
--- a/patches/server/0243-Restore-vanilla-default-mob-spawn-range-and-water-an.patch
+++ b/patches/server/0251-Restore-vanilla-default-mob-spawn-range-and-water-an.patch
diff --git a/patches/server/0244-Slime-Pathfinder-Events.patch b/patches/server/0252-Slime-Pathfinder-Events.patch
index e6984e42ea..e6984e42ea 100644
--- a/patches/server/0244-Slime-Pathfinder-Events.patch
+++ b/patches/server/0252-Slime-Pathfinder-Events.patch
diff --git a/patches/server/0245-Configurable-speed-for-water-flowing-over-lava.patch b/patches/server/0253-Configurable-speed-for-water-flowing-over-lava.patch
index 05e4b14d22..05e4b14d22 100644
--- a/patches/server/0245-Configurable-speed-for-water-flowing-over-lava.patch
+++ b/patches/server/0253-Configurable-speed-for-water-flowing-over-lava.patch
diff --git a/patches/server/0246-Optimize-CraftBlockData-Creation.patch b/patches/server/0254-Optimize-CraftBlockData-Creation.patch
index 19a0baf0b7..19a0baf0b7 100644
--- a/patches/server/0246-Optimize-CraftBlockData-Creation.patch
+++ b/patches/server/0254-Optimize-CraftBlockData-Creation.patch
diff --git a/patches/server/0247-Optimize-MappedRegistry.patch b/patches/server/0255-Optimize-MappedRegistry.patch
index 70684ff905..70684ff905 100644
--- a/patches/server/0247-Optimize-MappedRegistry.patch
+++ b/patches/server/0255-Optimize-MappedRegistry.patch
diff --git a/patches/server/0248-Add-PhantomPreSpawnEvent.patch b/patches/server/0256-Add-PhantomPreSpawnEvent.patch
index f4862ce10d..f4862ce10d 100644
--- a/patches/server/0248-Add-PhantomPreSpawnEvent.patch
+++ b/patches/server/0256-Add-PhantomPreSpawnEvent.patch
diff --git a/patches/server/0249-Add-More-Creeper-API.patch b/patches/server/0257-Add-More-Creeper-API.patch
index fac9477cb0..701306ca69 100644
--- a/patches/server/0249-Add-More-Creeper-API.patch
+++ b/patches/server/0257-Add-More-Creeper-API.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] Add More Creeper API
diff --git a/src/main/java/net/minecraft/world/entity/monster/Creeper.java b/src/main/java/net/minecraft/world/entity/monster/Creeper.java
-index bc493838420a6857ebc86f84cabdc1b6e3e637a4..8c328d72c42ccaa6891249cc700b70bb34c09545 100644
+index bc493838420a6857ebc86f84cabdc1b6e3e637a4..e0f71dc12cfc28710cacfbc372026f556dcab165 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Creeper.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Creeper.java
@@ -133,7 +133,7 @@ public class Creeper extends Monster implements PowerableMob {
diff --git a/patches/server/0250-Inventory-removeItemAnySlot.patch b/patches/server/0258-Inventory-removeItemAnySlot.patch
index 533e72fb45..533e72fb45 100644
--- a/patches/server/0250-Inventory-removeItemAnySlot.patch
+++ b/patches/server/0258-Inventory-removeItemAnySlot.patch
diff --git a/patches/server/0251-Make-CraftWorld-loadChunk-int-int-false-load-unconve.patch b/patches/server/0259-Make-CraftWorld-loadChunk-int-int-false-load-unconve.patch
index 3994515245..de9fb155cb 100644
--- a/patches/server/0251-Make-CraftWorld-loadChunk-int-int-false-load-unconve.patch
+++ b/patches/server/0259-Make-CraftWorld-loadChunk-int-int-false-load-unconve.patch
@@ -6,10 +6,10 @@ Subject: [PATCH] Make CraftWorld#loadChunk(int, int, false) load unconverted
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-index 124c1b07067a889ffeb5b9994b0b3be4d3e64540..153c2e8bc317d9bff834645102235434e82716e1 100644
+index ff842f952d744a13eb563407edc21d03d43ddd66..ef0bff86d3f5f0c404f66b3e2e0a4976006909ee 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-@@ -390,7 +390,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+@@ -389,7 +389,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@Override
public boolean loadChunk(int x, int z, boolean generate) {
org.spigotmc.AsyncCatcher.catchOp("chunk load"); // Spigot
diff --git a/patches/server/0253-Add-ray-tracing-methods-to-LivingEntity.patch b/patches/server/0260-Add-ray-tracing-methods-to-LivingEntity.patch
index 9faee7709b..5e366ff178 100644
--- a/patches/server/0253-Add-ray-tracing-methods-to-LivingEntity.patch
+++ b/patches/server/0260-Add-ray-tracing-methods-to-LivingEntity.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Add ray tracing methods to LivingEntity
diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java
-index 0cf818fceddd76e7704fdc6625456787856b2815..ccdee183f02ab55723e16f41efce55dc51e96297 100644
+index 98cd851cdc67ecd9296ec5a8e56141638e108109..4bfccf77d68e8bcfb9b7379bf04a70515b1ebbcd 100644
--- a/src/main/java/net/minecraft/server/MCUtil.java
+++ b/src/main/java/net/minecraft/server/MCUtil.java
-@@ -493,6 +493,18 @@ public final class MCUtil {
+@@ -508,6 +508,18 @@ public final class MCUtil {
return getNMSWorld(entity.getWorld());
}
diff --git a/patches/server/0254-Expose-attack-cooldown-methods-for-Player.patch b/patches/server/0261-Expose-attack-cooldown-methods-for-Player.patch
index 8806788a97..fd448ce851 100644
--- a/patches/server/0254-Expose-attack-cooldown-methods-for-Player.patch
+++ b/patches/server/0261-Expose-attack-cooldown-methods-for-Player.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] Expose attack cooldown methods for Player
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
-index f5259ada3e21b036fd3e3b96d727f1c8c4a042b8..d445ebe4b5055a270b679c353abcecf6dea3dc8c 100644
+index 69c3602abfddc9c065736cf08c32f88029df0e5c..da6511b0842e25eca537dd9df92d63e49e4290ad 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -2510,6 +2510,21 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
diff --git a/patches/server/0255-Improve-death-events.patch b/patches/server/0262-Improve-death-events.patch
index ee4fb0dd60..f8f6f3fd1a 100644
--- a/patches/server/0255-Improve-death-events.patch
+++ b/patches/server/0262-Improve-death-events.patch
@@ -19,10 +19,10 @@ maybe more (please check patch overrides for drops for more):
- players, armor stands, foxes, chested donkeys/llamas
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-index 522c8791edd87feb6cb32ef8e621ae35e53c9cb1..1b3188837069622baaba90c80fe387abfbfad10a 100644
+index 4b9af6ef008a297438bfc583025d235d07d9b780..6d95d572092ad50ffa92c2e1731fd59c6dfd7a44 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-@@ -230,6 +230,10 @@ public class ServerPlayer extends Player {
+@@ -231,6 +231,10 @@ public class ServerPlayer extends Player {
public int latency;
public boolean wonGame;
private int containerUpdateDelay; // Paper
@@ -33,7 +33,7 @@ index 522c8791edd87feb6cb32ef8e621ae35e53c9cb1..1b3188837069622baaba90c80fe387ab
// CraftBukkit start
public String displayName;
-@@ -800,6 +804,15 @@ public class ServerPlayer extends Player {
+@@ -816,6 +820,15 @@ public class ServerPlayer extends Player {
String deathmessage = defaultMessage.getString();
this.keepLevel = keepInventory; // SPIGOT-2222: pre-set keepLevel
org.bukkit.event.entity.PlayerDeathEvent event = CraftEventFactory.callPlayerDeathEvent(this, loot, PaperAdventure.asAdventure(defaultMessage), defaultMessage.getString(), keepInventory); // Paper - Adventure
@@ -49,7 +49,7 @@ index 522c8791edd87feb6cb32ef8e621ae35e53c9cb1..1b3188837069622baaba90c80fe387ab
// SPIGOT-943 - only call if they have an inventory open
if (this.containerMenu != this.inventoryMenu) {
-@@ -945,8 +958,17 @@ public class ServerPlayer extends Player {
+@@ -961,8 +974,17 @@ public class ServerPlayer extends Player {
}
}
}
@@ -310,7 +310,7 @@ index f94a74728bd7c02a7f8245c92e7916f0b669ee0d..cd54fa8f7bbcb6036e90f4ef7cdc01d7
this.gameEvent(GameEvent.ENTITY_DIE);
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
-index d445ebe4b5055a270b679c353abcecf6dea3dc8c..df164a6fe8d53d34db93f4f1f2af6a9c1c98a7e8 100644
+index da6511b0842e25eca537dd9df92d63e49e4290ad..1b0f744423c4a61f85ad901b5a71b1ebe52a7cdd 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -2074,7 +2074,14 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
diff --git a/patches/server/0256-Allow-chests-to-be-placed-with-NBT-data.patch b/patches/server/0263-Allow-chests-to-be-placed-with-NBT-data.patch
index e03ccbcd5a..e03ccbcd5a 100644
--- a/patches/server/0256-Allow-chests-to-be-placed-with-NBT-data.patch
+++ b/patches/server/0263-Allow-chests-to-be-placed-with-NBT-data.patch
diff --git a/patches/server/0257-Mob-Pathfinding-API.patch b/patches/server/0264-Mob-Pathfinding-API.patch
index 49c958043d..49c958043d 100644
--- a/patches/server/0257-Mob-Pathfinding-API.patch
+++ b/patches/server/0264-Mob-Pathfinding-API.patch
diff --git a/patches/server/0258-Implement-an-API-for-CanPlaceOn-and-CanDestroy-NBT-v.patch b/patches/server/0265-Implement-an-API-for-CanPlaceOn-and-CanDestroy-NBT-v.patch
index 4ae690f9d8..4ae690f9d8 100644
--- a/patches/server/0258-Implement-an-API-for-CanPlaceOn-and-CanDestroy-NBT-v.patch
+++ b/patches/server/0265-Implement-an-API-for-CanPlaceOn-and-CanDestroy-NBT-v.patch
diff --git a/patches/server/0259-Prevent-chunk-loading-from-Fluid-Flowing.patch b/patches/server/0266-Prevent-chunk-loading-from-Fluid-Flowing.patch
index 8e59eff59d..8e59eff59d 100644
--- a/patches/server/0259-Prevent-chunk-loading-from-Fluid-Flowing.patch
+++ b/patches/server/0266-Prevent-chunk-loading-from-Fluid-Flowing.patch
diff --git a/patches/server/0260-Prevent-Mob-AI-Rules-from-Loading-Chunks.patch b/patches/server/0267-Prevent-Mob-AI-Rules-from-Loading-Chunks.patch
index 12a3938c2d..12a3938c2d 100644
--- a/patches/server/0260-Prevent-Mob-AI-Rules-from-Loading-Chunks.patch
+++ b/patches/server/0267-Prevent-Mob-AI-Rules-from-Loading-Chunks.patch
diff --git a/patches/server/0261-Prevent-mob-spawning-from-loading-generating-chunks.patch b/patches/server/0268-Prevent-mob-spawning-from-loading-generating-chunks.patch
index 7c943a7345..7c943a7345 100644
--- a/patches/server/0261-Prevent-mob-spawning-from-loading-generating-chunks.patch
+++ b/patches/server/0268-Prevent-mob-spawning-from-loading-generating-chunks.patch
diff --git a/patches/server/0262-Implement-furnace-cook-speed-multiplier-API.patch b/patches/server/0269-Implement-furnace-cook-speed-multiplier-API.patch
index ef1f41e68e..ef1f41e68e 100644
--- a/patches/server/0262-Implement-furnace-cook-speed-multiplier-API.patch
+++ b/patches/server/0269-Implement-furnace-cook-speed-multiplier-API.patch
diff --git a/patches/server/0263-Catch-JsonParseException-in-Entity-and-TE-names.patch b/patches/server/0270-Catch-JsonParseException-in-Entity-and-TE-names.patch
index becfaf70e5..6b2d2dcdad 100644
--- a/patches/server/0263-Catch-JsonParseException-in-Entity-and-TE-names.patch
+++ b/patches/server/0270-Catch-JsonParseException-in-Entity-and-TE-names.patch
@@ -13,19 +13,19 @@ Shulkers) may need to be changed in order for it to re-save properly
No more crashing though.
diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java
-index ccdee183f02ab55723e16f41efce55dc51e96297..162aa7718488a74980843944e0d026ccfd5a65a5 100644
+index 40d033e8b7c29269a5e194f80c8bccc67836e28d..b575d73ae0ff2e4f09a6a1f6fb061ca3da2cedf1 100644
--- a/src/main/java/net/minecraft/server/MCUtil.java
+++ b/src/main/java/net/minecraft/server/MCUtil.java
-@@ -7,6 +7,8 @@ import it.unimi.dsi.fastutil.objects.ObjectRBTreeSet;
+@@ -12,6 +12,8 @@ import it.unimi.dsi.fastutil.objects.ObjectRBTreeSet;
import java.lang.ref.Cleaner;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
+import net.minecraft.nbt.CompoundTag;
+import net.minecraft.network.chat.Component;
- import net.minecraft.server.level.ServerLevel;
- import net.minecraft.world.entity.Entity;
- import net.minecraft.world.level.ChunkPos;
-@@ -524,6 +526,21 @@ public final class MCUtil {
+ import net.minecraft.server.level.ChunkHolder;
+ import net.minecraft.server.level.ChunkMap;
+ import net.minecraft.server.level.DistanceManager;
+@@ -539,6 +541,21 @@ public final class MCUtil {
}
}
@@ -44,8 +44,8 @@ index ccdee183f02ab55723e16f41efce55dc51e96297..162aa7718488a74980843944e0d026cc
+ return null;
+ }
+
- public static int getTicketLevelFor(net.minecraft.world.level.chunk.ChunkStatus status) {
- return net.minecraft.server.level.ChunkMap.MAX_VIEW_DISTANCE + net.minecraft.world.level.chunk.ChunkStatus.getDistance(status);
+ public static ChunkStatus getChunkStatus(ChunkHolder chunk) {
+ return chunk.getChunkHolderStatus();
}
diff --git a/src/main/java/net/minecraft/world/level/BaseCommandBlock.java b/src/main/java/net/minecraft/world/level/BaseCommandBlock.java
index a0728e95251e8110bcecd00512c7a266fe120794..da504702bc9423774b35dff792d2dbe7fc270fe3 100644
diff --git a/patches/server/0264-Honor-EntityAgeable.ageLock.patch b/patches/server/0271-Honor-EntityAgeable.ageLock.patch
index 3c2db99373..3c2db99373 100644
--- a/patches/server/0264-Honor-EntityAgeable.ageLock.patch
+++ b/patches/server/0271-Honor-EntityAgeable.ageLock.patch
diff --git a/patches/server/0265-Configurable-connection-throttle-kick-message.patch b/patches/server/0272-Configurable-connection-throttle-kick-message.patch
index 388accb3aa..388accb3aa 100644
--- a/patches/server/0265-Configurable-connection-throttle-kick-message.patch
+++ b/patches/server/0272-Configurable-connection-throttle-kick-message.patch
diff --git a/patches/server/0266-Hook-into-CB-plugin-rewrites.patch b/patches/server/0273-Hook-into-CB-plugin-rewrites.patch
index a3aff98067..a3aff98067 100644
--- a/patches/server/0266-Hook-into-CB-plugin-rewrites.patch
+++ b/patches/server/0273-Hook-into-CB-plugin-rewrites.patch
diff --git a/patches/server/0267-PreSpawnerSpawnEvent.patch b/patches/server/0274-PreSpawnerSpawnEvent.patch
index ad93f9fbae..ad93f9fbae 100644
--- a/patches/server/0267-PreSpawnerSpawnEvent.patch
+++ b/patches/server/0274-PreSpawnerSpawnEvent.patch
diff --git a/patches/server/0268-Add-LivingEntity-getTargetEntity.patch b/patches/server/0275-Add-LivingEntity-getTargetEntity.patch
index 42ee44744d..42ee44744d 100644
--- a/patches/server/0268-Add-LivingEntity-getTargetEntity.patch
+++ b/patches/server/0275-Add-LivingEntity-getTargetEntity.patch
diff --git a/patches/server/0269-Add-sun-related-API.patch b/patches/server/0276-Add-sun-related-API.patch
index 3f3308e435..e19d11236a 100644
--- a/patches/server/0269-Add-sun-related-API.patch
+++ b/patches/server/0276-Add-sun-related-API.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Add sun related API
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-index 0d939dc855d4e03df9a95d318e769d842892d46d..4003325fa6d4e8391dd6496df620f29265fe1cf9 100644
+index ef0bff86d3f5f0c404f66b3e2e0a4976006909ee..3aa2e80e7d30d8824fd7f009282adfd8712cbb55 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-@@ -690,6 +690,13 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+@@ -689,6 +689,13 @@ public class CraftWorld extends CraftRegionAccessor implements World {
}
}
diff --git a/patches/server/0270-Turtle-API.patch b/patches/server/0277-Turtle-API.patch
index 1bc6544713..1bc6544713 100644
--- a/patches/server/0270-Turtle-API.patch
+++ b/patches/server/0277-Turtle-API.patch
diff --git a/patches/server/0271-Call-player-spectator-target-events-and-improve-impl.patch b/patches/server/0278-Call-player-spectator-target-events-and-improve-impl.patch
index bc8632e576..19b55a59dc 100644
--- a/patches/server/0271-Call-player-spectator-target-events-and-improve-impl.patch
+++ b/patches/server/0278-Call-player-spectator-target-events-and-improve-impl.patch
@@ -19,10 +19,10 @@ spectate the target entity.
Co-authored-by: Spottedleaf <[email protected]>
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-index 56b1c585d1c330bf9b904ebf8ef0b8be47102aa3..e4f991578d4ee581e65f2edb7d32640ff36a01bd 100644
+index 6d95d572092ad50ffa92c2e1731fd59c6dfd7a44..f48866aff156eb1fb5e673b93becada744a04bc5 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-@@ -1875,14 +1875,58 @@ public class ServerPlayer extends Player {
+@@ -1891,14 +1891,58 @@ public class ServerPlayer extends Player {
}
public void setCamera(@Nullable Entity entity) {
diff --git a/patches/server/0272-MC-50319-Check-other-worlds-for-shooter-of-projectil.patch b/patches/server/0279-MC-50319-Check-other-worlds-for-shooter-of-projectil.patch
index b766300549..b766300549 100644
--- a/patches/server/0272-MC-50319-Check-other-worlds-for-shooter-of-projectil.patch
+++ b/patches/server/0279-MC-50319-Check-other-worlds-for-shooter-of-projectil.patch
diff --git a/patches/server/0273-Add-more-Witch-API.patch b/patches/server/0280-Add-more-Witch-API.patch
index 4fdcae61a9..4fdcae61a9 100644
--- a/patches/server/0273-Add-more-Witch-API.patch
+++ b/patches/server/0280-Add-more-Witch-API.patch
diff --git a/patches/server/0274-Check-Drowned-for-Villager-Aggression-Config.patch b/patches/server/0281-Check-Drowned-for-Villager-Aggression-Config.patch
index ec62c27d6f..ec62c27d6f 100644
--- a/patches/server/0274-Check-Drowned-for-Villager-Aggression-Config.patch
+++ b/patches/server/0281-Check-Drowned-for-Villager-Aggression-Config.patch
diff --git a/patches/server/0275-Add-option-to-prevent-players-from-moving-into-unloa.patch b/patches/server/0282-Add-option-to-prevent-players-from-moving-into-unloa.patch
index bcbabba356..bcbabba356 100644
--- a/patches/server/0275-Add-option-to-prevent-players-from-moving-into-unloa.patch
+++ b/patches/server/0282-Add-option-to-prevent-players-from-moving-into-unloa.patch
diff --git a/patches/server/0276-Reset-players-airTicks-on-respawn.patch b/patches/server/0283-Reset-players-airTicks-on-respawn.patch
index ca5fce40d8..699c6e51a7 100644
--- a/patches/server/0276-Reset-players-airTicks-on-respawn.patch
+++ b/patches/server/0283-Reset-players-airTicks-on-respawn.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Reset players airTicks on respawn
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-index be79f80270a7400451dcaac55fba8d3ab7bdda52..5f10a2d21553a8dc8c03ea5951190860ee5a4615 100644
+index f48866aff156eb1fb5e673b93becada744a04bc5..4c35529c7ed67c2432ac67e7d8ffe295892757ff 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-@@ -2288,6 +2288,7 @@ public class ServerPlayer extends Player {
+@@ -2304,6 +2304,7 @@ public class ServerPlayer extends Player {
this.setHealth(this.getMaxHealth());
this.stopUsingItem(); // CraftBukkit - SPIGOT-6682: Clear active item on reset
diff --git a/patches/server/0277-Don-t-sleep-after-profile-lookups-if-not-needed.patch b/patches/server/0284-Don-t-sleep-after-profile-lookups-if-not-needed.patch
index c4f99ad87b..c4f99ad87b 100644
--- a/patches/server/0277-Don-t-sleep-after-profile-lookups-if-not-needed.patch
+++ b/patches/server/0284-Don-t-sleep-after-profile-lookups-if-not-needed.patch
diff --git a/patches/server/0278-Improve-Server-Thread-Pool-and-Thread-Priorities.patch b/patches/server/0285-Improve-Server-Thread-Pool-and-Thread-Priorities.patch
index 02b480cd0c..6d5902676e 100644
--- a/patches/server/0278-Improve-Server-Thread-Pool-and-Thread-Priorities.patch
+++ b/patches/server/0285-Improve-Server-Thread-Pool-and-Thread-Priorities.patch
@@ -58,7 +58,7 @@ index 336a26733b5bf73455f8ec10347c1e08b8e866f7..4fce18c52c8144460ebf0c1e336dce71
return executorService;
}
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
-index 560e213f39d82613bd1bfcfb4eb3bd7aeed1c0c6..3d1c7bfeafbad2c5b7275f75d263a3817bd3a8aa 100644
+index 802b7767dd0878cf6d2e52bea74d5664f7d0664f..df9a67733c757ab128c11d73d001dcb8624d0283 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -306,6 +306,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
diff --git a/patches/server/0279-Optimize-World-Time-Updates.patch b/patches/server/0286-Optimize-World-Time-Updates.patch
index 9b24f9447b..036816fc70 100644
--- a/patches/server/0279-Optimize-World-Time-Updates.patch
+++ b/patches/server/0286-Optimize-World-Time-Updates.patch
@@ -8,7 +8,7 @@ the updates per world, so that we can re-use the same packet
object for every player unless they have per-player time enabled.
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
-index 3d1c7bfeafbad2c5b7275f75d263a3817bd3a8aa..89c0c0d0d3458f38a1a0b91617b84f439af667c8 100644
+index df9a67733c757ab128c11d73d001dcb8624d0283..c5a118b1aab0654024a55ce5eae86aff8346c3d6 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -1378,12 +1378,24 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
diff --git a/patches/server/0280-Restore-custom-InventoryHolder-support.patch b/patches/server/0287-Restore-custom-InventoryHolder-support.patch
index b6b1612284..b6b1612284 100644
--- a/patches/server/0280-Restore-custom-InventoryHolder-support.patch
+++ b/patches/server/0287-Restore-custom-InventoryHolder-support.patch
diff --git a/patches/server/0281-Use-Vanilla-Minecart-Speeds.patch b/patches/server/0288-Use-Vanilla-Minecart-Speeds.patch
index 9fde4a8e53..9fde4a8e53 100644
--- a/patches/server/0281-Use-Vanilla-Minecart-Speeds.patch
+++ b/patches/server/0288-Use-Vanilla-Minecart-Speeds.patch
diff --git a/patches/server/0282-Fix-SpongeAbsortEvent-handling.patch b/patches/server/0289-Fix-SpongeAbsortEvent-handling.patch
index a527364310..a527364310 100644
--- a/patches/server/0282-Fix-SpongeAbsortEvent-handling.patch
+++ b/patches/server/0289-Fix-SpongeAbsortEvent-handling.patch
diff --git a/patches/server/0283-Don-t-allow-digging-into-unloaded-chunks.patch b/patches/server/0290-Don-t-allow-digging-into-unloaded-chunks.patch
index 333ff2365a..333ff2365a 100644
--- a/patches/server/0283-Don-t-allow-digging-into-unloaded-chunks.patch
+++ b/patches/server/0290-Don-t-allow-digging-into-unloaded-chunks.patch
diff --git a/patches/server/0284-Make-the-default-permission-message-configurable.patch b/patches/server/0291-Make-the-default-permission-message-configurable.patch
index 2548eff438..7997cc7347 100644
--- a/patches/server/0284-Make-the-default-permission-message-configurable.patch
+++ b/patches/server/0291-Make-the-default-permission-message-configurable.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Make the default permission message configurable
diff --git a/src/main/java/io/papermc/paper/command/PaperCommand.java b/src/main/java/io/papermc/paper/command/PaperCommand.java
-index b3a58bf4b654e336826dc04da9e2f80ff8b9a9a7..cd4936ef114b504df8649fba8f1823d94a4bb2a2 100644
+index 8e773f522521d2dd6349c87b582a3337b76f161f..395c43f6440c1e0e47919eef096ea8a8d552ccec 100644
--- a/src/main/java/io/papermc/paper/command/PaperCommand.java
+++ b/src/main/java/io/papermc/paper/command/PaperCommand.java
-@@ -74,7 +74,7 @@ public final class PaperCommand extends Command {
+@@ -76,7 +76,7 @@ public final class PaperCommand extends Command {
if (sender.hasPermission(BASE_PERM + permission) || sender.hasPermission("bukkit.command.paper")) {
return true;
}
@@ -18,7 +18,7 @@ index b3a58bf4b654e336826dc04da9e2f80ff8b9a9a7..cd4936ef114b504df8649fba8f1823d9
}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-index 71415a6ca5bd61fa5652006ed748048d65a0502b..f8640a3a147322d99dc23a28de0a77692205ff75 100644
+index 11d7f2d41da52cd0fdb96310153cd6d5547a6b8f..fec355dfc7e6353759276f82e6677fd9607e6e7c 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -2622,6 +2622,16 @@ public final class CraftServer implements Server {
diff --git a/patches/server/0285-Prevent-rayTrace-from-loading-chunks.patch b/patches/server/0292-Prevent-rayTrace-from-loading-chunks.patch
index dd9d69d953..dd9d69d953 100644
--- a/patches/server/0285-Prevent-rayTrace-from-loading-chunks.patch
+++ b/patches/server/0292-Prevent-rayTrace-from-loading-chunks.patch
diff --git a/patches/server/0286-Handle-Large-Packets-disconnecting-client.patch b/patches/server/0293-Handle-Large-Packets-disconnecting-client.patch
index 49ba10fe12..49ba10fe12 100644
--- a/patches/server/0286-Handle-Large-Packets-disconnecting-client.patch
+++ b/patches/server/0293-Handle-Large-Packets-disconnecting-client.patch
diff --git a/patches/server/0287-force-entity-dismount-during-teleportation.patch b/patches/server/0294-force-entity-dismount-during-teleportation.patch
index cdbeee7cd1..8f4bc21a21 100644
--- a/patches/server/0287-force-entity-dismount-during-teleportation.patch
+++ b/patches/server/0294-force-entity-dismount-during-teleportation.patch
@@ -20,10 +20,10 @@ this is going to be the best soultion all around.
Improvements/suggestions welcome!
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-index 5f10a2d21553a8dc8c03ea5951190860ee5a4615..b81314654d562036680666bd95be4ec21d9b66e1 100644
+index 4c35529c7ed67c2432ac67e7d8ffe295892757ff..f91da5bc234a8f1c120261823a1a4e4216513329 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-@@ -1335,11 +1335,13 @@ public class ServerPlayer extends Player {
+@@ -1351,11 +1351,13 @@ public class ServerPlayer extends Player {
}
}
@@ -41,7 +41,7 @@ index 5f10a2d21553a8dc8c03ea5951190860ee5a4615..b81314654d562036680666bd95be4ec2
if (entity1 != entity && this.connection != null) {
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
-index ed79a9d5a822370a9a285e58773669a00b159054..f02b0afc1ef85622bc801f526e1ed476f9722c2e 100644
+index 29c71c951ce7114dfb24f0c99c3bf8c2a6f6144f..cb2b47df90386ffb1305062f3f34a63549151e8b 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -2315,11 +2315,16 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
diff --git a/patches/server/0288-Add-more-Zombie-API.patch b/patches/server/0295-Add-more-Zombie-API.patch
index d4683e84c2..d4683e84c2 100644
--- a/patches/server/0288-Add-more-Zombie-API.patch
+++ b/patches/server/0295-Add-more-Zombie-API.patch
diff --git a/patches/server/0289-Book-Size-Limits.patch b/patches/server/0296-Book-Size-Limits.patch
index 4a91022d7e..4a91022d7e 100644
--- a/patches/server/0289-Book-Size-Limits.patch
+++ b/patches/server/0296-Book-Size-Limits.patch
diff --git a/patches/server/0290-Add-PlayerConnectionCloseEvent.patch b/patches/server/0297-Add-PlayerConnectionCloseEvent.patch
index d9509c863c..d9509c863c 100644
--- a/patches/server/0290-Add-PlayerConnectionCloseEvent.patch
+++ b/patches/server/0297-Add-PlayerConnectionCloseEvent.patch
diff --git a/patches/server/0291-Prevent-Enderman-from-loading-chunks.patch b/patches/server/0298-Prevent-Enderman-from-loading-chunks.patch
index 0eadb94123..0eadb94123 100644
--- a/patches/server/0291-Prevent-Enderman-from-loading-chunks.patch
+++ b/patches/server/0298-Prevent-Enderman-from-loading-chunks.patch
diff --git a/patches/server/0292-Add-APIs-to-replace-OfflinePlayer-getLastPlayed.patch b/patches/server/0299-Add-APIs-to-replace-OfflinePlayer-getLastPlayed.patch
index 98ca430f21..f79d5c3d9b 100644
--- a/patches/server/0292-Add-APIs-to-replace-OfflinePlayer-getLastPlayed.patch
+++ b/patches/server/0299-Add-APIs-to-replace-OfflinePlayer-getLastPlayed.patch
@@ -16,10 +16,10 @@ intent to remove) and replace it with two new methods, clearly named and
documented as to their purpose.
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-index b81314654d562036680666bd95be4ec21d9b66e1..3f9b13048eff59094a229d1a41d219bbd7f3eb01 100644
+index f91da5bc234a8f1c120261823a1a4e4216513329..ef5a1bdbb059a81763b1d630846dd69685842c19 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-@@ -230,6 +230,7 @@ public class ServerPlayer extends Player {
+@@ -231,6 +231,7 @@ public class ServerPlayer extends Player {
public int latency;
public boolean wonGame;
private int containerUpdateDelay; // Paper
@@ -28,13 +28,13 @@ index b81314654d562036680666bd95be4ec21d9b66e1..3f9b13048eff59094a229d1a41d219bb
public boolean queueHealthUpdatePacket = false;
public net.minecraft.network.protocol.game.ClientboundSetHealthPacket queuedHealthUpdatePacket;
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
-index f8ad63b05ece77cf973ef41ef40111780f0d2d04..bb0c40246f70deecf10b9540d6cba7f65cc91372 100644
+index c974120dda3bac8a4a74c4b4d8ddcfb802f792dc..7db8289fe3447f5ca403c5a66fc598b2055f4569 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
-@@ -178,6 +178,7 @@ public abstract class PlayerList {
- }
+@@ -179,6 +179,7 @@ public abstract class PlayerList {
public void placeNewPlayer(Connection connection, ServerPlayer player) {
+ player.isRealPlayer = true; // Paper - Chunk priority
+ player.loginTime = System.currentTimeMillis(); // Paper
GameProfile gameprofile = player.getGameProfile();
GameProfileCache usercache = this.server.getProfileCache();
@@ -106,7 +106,7 @@ index e7442952ef1f03969949014492a7ddc6d0796ba5..d7823d7dc88cfba6f6ac9dae220e03de
public Location getLastDeathLocation() {
if (this.getData().contains("LastDeathLocation", 10)) {
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
-index 0fcde65af63c4fcfbbef5875bec759b209cfd5f1..1a7f5978ad9ab1ee15f2e40e8109cf6dad5f890c 100644
+index 1b0f744423c4a61f85ad901b5a71b1ebe52a7cdd..e2bf6be0788158602d2e25bd7ba8a72caad6cbfd 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -168,6 +168,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
diff --git a/patches/server/0293-Workaround-for-vehicle-tracking-issue-on-disconnect.patch b/patches/server/0300-Workaround-for-vehicle-tracking-issue-on-disconnect.patch
index 303280c1ee..8d53da7d4e 100644
--- a/patches/server/0293-Workaround-for-vehicle-tracking-issue-on-disconnect.patch
+++ b/patches/server/0300-Workaround-for-vehicle-tracking-issue-on-disconnect.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Workaround for vehicle tracking issue on disconnect
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-index 3f9b13048eff59094a229d1a41d219bbd7f3eb01..3d85bf30b146401bfdbc4056cdbf03f263b4e9a9 100644
+index ef5a1bdbb059a81763b1d630846dd69685842c19..21b585ee91be0636e9d8f223106b5daa7ffb9ee6 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-@@ -1577,6 +1577,13 @@ public class ServerPlayer extends Player {
+@@ -1593,6 +1593,13 @@ public class ServerPlayer extends Player {
public void disconnect() {
this.disconnected = true;
this.ejectPassengers();
diff --git a/patches/server/0294-Block-Entity-remove-from-being-called-on-Players.patch b/patches/server/0301-Block-Entity-remove-from-being-called-on-Players.patch
index d734c87a14..d52db88429 100644
--- a/patches/server/0294-Block-Entity-remove-from-being-called-on-Players.patch
+++ b/patches/server/0301-Block-Entity-remove-from-being-called-on-Players.patch
@@ -12,7 +12,7 @@ Player we will look at limiting the scope of this change. It appears to
be unintentional in the few cases we've seen so far.
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
-index 1a7f5978ad9ab1ee15f2e40e8109cf6dad5f890c..8a349c179e9abcda140546c56ea884422b409b5d 100644
+index e2bf6be0788158602d2e25bd7ba8a72caad6cbfd..86447a824d9749f85a6378682d4a6f74ca19875d 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -2557,6 +2557,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
diff --git a/patches/server/0295-BlockDestroyEvent.patch b/patches/server/0302-BlockDestroyEvent.patch
index 38b61505fb..38b61505fb 100644
--- a/patches/server/0295-BlockDestroyEvent.patch
+++ b/patches/server/0302-BlockDestroyEvent.patch
diff --git a/patches/server/0296-Async-command-map-building.patch b/patches/server/0303-Async-command-map-building.patch
index 8a809e4308..cab55a5ab5 100644
--- a/patches/server/0296-Async-command-map-building.patch
+++ b/patches/server/0303-Async-command-map-building.patch
@@ -53,7 +53,7 @@ index 2bf67468a6c745bc6243c65210477ba129bfcb07..c4315531f93f4ed68b4621157b025728
event.getPlayer().getServer().getPluginManager().callEvent(event);
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
-index 89c0c0d0d3458f38a1a0b91617b84f439af667c8..6f6125c3896fb388e0840d3e224b826bfa10eec0 100644
+index c5a118b1aab0654024a55ce5eae86aff8346c3d6..a53e1bc43903c10083b713b2c5ea5459ddfd4e27 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -879,6 +879,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
diff --git a/patches/server/0297-Implement-Brigadier-Mojang-API.patch b/patches/server/0304-Implement-Brigadier-Mojang-API.patch
index df0d54f647..df0d54f647 100644
--- a/patches/server/0297-Implement-Brigadier-Mojang-API.patch
+++ b/patches/server/0304-Implement-Brigadier-Mojang-API.patch
diff --git a/patches/server/0298-Fix-Custom-Shapeless-Custom-Crafting-Recipes.patch b/patches/server/0305-Fix-Custom-Shapeless-Custom-Crafting-Recipes.patch
index 903ba48692..903ba48692 100644
--- a/patches/server/0298-Fix-Custom-Shapeless-Custom-Crafting-Recipes.patch
+++ b/patches/server/0305-Fix-Custom-Shapeless-Custom-Crafting-Recipes.patch
diff --git a/patches/server/0299-Limit-Client-Sign-length-more.patch b/patches/server/0306-Limit-Client-Sign-length-more.patch
index 7444d0ad49..7444d0ad49 100644
--- a/patches/server/0299-Limit-Client-Sign-length-more.patch
+++ b/patches/server/0306-Limit-Client-Sign-length-more.patch
diff --git a/patches/server/0300-Don-t-check-ConvertSigns-boolean-every-sign-save.patch b/patches/server/0307-Don-t-check-ConvertSigns-boolean-every-sign-save.patch
index 0d3af0b6f8..0d3af0b6f8 100644
--- a/patches/server/0300-Don-t-check-ConvertSigns-boolean-every-sign-save.patch
+++ b/patches/server/0307-Don-t-check-ConvertSigns-boolean-every-sign-save.patch
diff --git a/patches/server/0301-Optimize-Network-Manager-and-add-advanced-packet-sup.patch b/patches/server/0308-Optimize-Network-Manager-and-add-advanced-packet-sup.patch
index 77e32e1bf6..77e32e1bf6 100644
--- a/patches/server/0301-Optimize-Network-Manager-and-add-advanced-packet-sup.patch
+++ b/patches/server/0308-Optimize-Network-Manager-and-add-advanced-packet-sup.patch
diff --git a/patches/server/0302-Handle-Oversized-Tile-Entities-in-chunks.patch b/patches/server/0309-Handle-Oversized-Tile-Entities-in-chunks.patch
index bcaddcfede..bcaddcfede 100644
--- a/patches/server/0302-Handle-Oversized-Tile-Entities-in-chunks.patch
+++ b/patches/server/0309-Handle-Oversized-Tile-Entities-in-chunks.patch
diff --git a/patches/server/0303-Set-Zombie-last-tick-at-start-of-drowning-process.patch b/patches/server/0310-Set-Zombie-last-tick-at-start-of-drowning-process.patch
index 6c82126b25..6c82126b25 100644
--- a/patches/server/0303-Set-Zombie-last-tick-at-start-of-drowning-process.patch
+++ b/patches/server/0310-Set-Zombie-last-tick-at-start-of-drowning-process.patch
diff --git a/patches/server/0304-Call-WhitelistToggleEvent-when-whitelist-is-toggled.patch b/patches/server/0311-Call-WhitelistToggleEvent-when-whitelist-is-toggled.patch
index 5f8a94bdb6..a8e13395a2 100644
--- a/patches/server/0304-Call-WhitelistToggleEvent-when-whitelist-is-toggled.patch
+++ b/patches/server/0311-Call-WhitelistToggleEvent-when-whitelist-is-toggled.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Call WhitelistToggleEvent when whitelist is toggled
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
-index bb0c40246f70deecf10b9540d6cba7f65cc91372..d20954b8d8683d6380ce9f4d87bd2e3a78f7488d 100644
+index 7db8289fe3447f5ca403c5a66fc598b2055f4569..3cb257544d95e82f8de2d693f510c15980aa27c8 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
-@@ -1128,6 +1128,7 @@ public abstract class PlayerList {
+@@ -1129,6 +1129,7 @@ public abstract class PlayerList {
}
public void setUsingWhiteList(boolean whitelistEnabled) {
diff --git a/patches/server/0305-Entity-getEntitySpawnReason.patch b/patches/server/0312-Entity-getEntitySpawnReason.patch
index a02bd42870..ba1c9d2221 100644
--- a/patches/server/0305-Entity-getEntitySpawnReason.patch
+++ b/patches/server/0312-Entity-getEntitySpawnReason.patch
@@ -10,10 +10,10 @@ persistenting Living Entity, SPAWNER for spawners,
or DEFAULT since data was not stored.
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index 293657617c32acfe70b0ab98939135e5ac6dae28..6ba45e1322b0d04433b2aac23413a9cd10c0b4c0 100644
+index 377ebed70c5008d69701bd919f22ad4506dd129c..427dfb5c7fe09e94aae617ecc1440fd1530fb857 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
-@@ -1213,6 +1213,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -1215,6 +1215,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
return true;
}
// Paper end
@@ -22,10 +22,10 @@ index 293657617c32acfe70b0ab98939135e5ac6dae28..6ba45e1322b0d04433b2aac23413a9cd
// Paper start
if (DEBUG_ENTITIES) {
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
-index d20954b8d8683d6380ce9f4d87bd2e3a78f7488d..7205f17da0383b22b6267843c92b31d8c0556caa 100644
+index 3cb257544d95e82f8de2d693f510c15980aa27c8..895d087fbdde840bd6b96b6c8d231fc9beeb2a0b 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
-@@ -347,7 +347,7 @@ public abstract class PlayerList {
+@@ -348,7 +348,7 @@ public abstract class PlayerList {
// CraftBukkit start
ServerLevel finalWorldServer = worldserver1;
Entity entity = EntityType.loadEntityRecursive(nbttagcompound1.getCompound("Entity"), finalWorldServer, (entity1) -> {
@@ -35,7 +35,7 @@ index d20954b8d8683d6380ce9f4d87bd2e3a78f7488d..7205f17da0383b22b6267843c92b31d8
});
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
-index f02b0afc1ef85622bc801f526e1ed476f9722c2e..5f613eac047703b6f1521fcd2d802e381d5f42d5 100644
+index cb2b47df90386ffb1305062f3f34a63549151e8b..482efc1c544cdd846f7330f4be43cc3e6eb397fc 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -74,6 +74,8 @@ import net.minecraft.world.InteractionHand;
@@ -105,7 +105,7 @@ index 0be0c7a323277093a6f8e476048eb9ee8712cbc9..c7e97263eee005fd673882e11c436542
// Spigot Start
if (org.bukkit.craftbukkit.event.CraftEventFactory.callSpawnerSpawnEvent(entity, pos).isCancelled()) {
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
-index 41920b979ab259fc27a57dde64abdba8c3be3185..6029cb7d8801c471e596ba027b7e408a27c44db9 100644
+index f70cc39d7fdd9308fd328007fcadbaab1780ad5f..cd958bc3c00f53ebaf9b3ae39564d3abb6c819a1 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
@@ -1249,5 +1249,10 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
diff --git a/patches/server/0306-Update-entity-Metadata-for-all-tracked-players.patch b/patches/server/0313-Update-entity-Metadata-for-all-tracked-players.patch
index 1ca13e50f5..1ca13e50f5 100644
--- a/patches/server/0306-Update-entity-Metadata-for-all-tracked-players.patch
+++ b/patches/server/0313-Update-entity-Metadata-for-all-tracked-players.patch
diff --git a/patches/server/0307-Fire-event-on-GS4-query.patch b/patches/server/0314-Fire-event-on-GS4-query.patch
index 445725e8b8..445725e8b8 100644
--- a/patches/server/0307-Fire-event-on-GS4-query.patch
+++ b/patches/server/0314-Fire-event-on-GS4-query.patch
diff --git a/patches/server/0308-Implement-PlayerPostRespawnEvent.patch b/patches/server/0315-Implement-PlayerPostRespawnEvent.patch
index d5672fc9ce..53f80b7443 100644
--- a/patches/server/0308-Implement-PlayerPostRespawnEvent.patch
+++ b/patches/server/0315-Implement-PlayerPostRespawnEvent.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Implement PlayerPostRespawnEvent
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
-index 7205f17da0383b22b6267843c92b31d8c0556caa..ee4d2f625629cf74f923592f11ecdb312de0c3ff 100644
+index 895d087fbdde840bd6b96b6c8d231fc9beeb2a0b..3f95cfe7d6e85a19c4d6c4ce2b662a4259c45477 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
-@@ -727,9 +727,14 @@ public abstract class PlayerList {
+@@ -728,9 +728,14 @@ public abstract class PlayerList {
boolean flag2 = false;
@@ -24,7 +24,7 @@ index 7205f17da0383b22b6267843c92b31d8c0556caa..ee4d2f625629cf74f923592f11ecdb31
ServerLevel worldserver1 = this.server.getLevel(entityplayer.getRespawnDimension());
if (worldserver1 != null) {
Optional optional;
-@@ -781,6 +786,7 @@ public abstract class PlayerList {
+@@ -782,6 +787,7 @@ public abstract class PlayerList {
location = respawnEvent.getRespawnLocation();
if (!flag) entityplayer.reset(); // SPIGOT-4785
@@ -32,7 +32,7 @@ index 7205f17da0383b22b6267843c92b31d8c0556caa..ee4d2f625629cf74f923592f11ecdb31
} else {
location.setWorld(worldserver.getWorld());
}
-@@ -838,6 +844,13 @@ public abstract class PlayerList {
+@@ -839,6 +845,13 @@ public abstract class PlayerList {
if (entityplayer.connection.isDisconnected()) {
this.save(entityplayer);
}
diff --git a/patches/server/0309-don-t-go-below-0-for-pickupDelay-breaks-picking-up-i.patch b/patches/server/0316-don-t-go-below-0-for-pickupDelay-breaks-picking-up-i.patch
index 94aa72db11..94aa72db11 100644
--- a/patches/server/0309-don-t-go-below-0-for-pickupDelay-breaks-picking-up-i.patch
+++ b/patches/server/0316-don-t-go-below-0-for-pickupDelay-breaks-picking-up-i.patch
diff --git a/patches/server/0310-Server-Tick-Events.patch b/patches/server/0317-Server-Tick-Events.patch
index a9e742012a..60fc617e7c 100644
--- a/patches/server/0310-Server-Tick-Events.patch
+++ b/patches/server/0317-Server-Tick-Events.patch
@@ -6,7 +6,7 @@ Subject: [PATCH] Server Tick Events
Fires event at start and end of a server tick
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
-index 6f6125c3896fb388e0840d3e224b826bfa10eec0..8c48544daae0f18a39511df12f7066fc0e383d2c 100644
+index a53e1bc43903c10083b713b2c5ea5459ddfd4e27..1d554a45097cdf0640788bb796b983f18af31a9f 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -1308,6 +1308,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
diff --git a/patches/server/0311-PlayerDeathEvent-getItemsToKeep.patch b/patches/server/0318-PlayerDeathEvent-getItemsToKeep.patch
index a059c795c7..b8dea8f8ed 100644
--- a/patches/server/0311-PlayerDeathEvent-getItemsToKeep.patch
+++ b/patches/server/0318-PlayerDeathEvent-getItemsToKeep.patch
@@ -8,10 +8,10 @@ Exposes a mutable array on items a player should keep on death
Example Usage: https://gist.github.com/aikar/5bb202de6057a051a950ce1f29feb0b4
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-index 3d85bf30b146401bfdbc4056cdbf03f263b4e9a9..02e81ba08b84f845b57a5148825ceb63313213a6 100644
+index 21b585ee91be0636e9d8f223106b5daa7ffb9ee6..d868c7f953cba9f7691c62edd2169ad26fc7d867 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-@@ -775,6 +775,46 @@ public class ServerPlayer extends Player {
+@@ -791,6 +791,46 @@ public class ServerPlayer extends Player {
});
}
@@ -58,7 +58,7 @@ index 3d85bf30b146401bfdbc4056cdbf03f263b4e9a9..02e81ba08b84f845b57a5148825ceb63
@Override
public void die(DamageSource damageSource) {
this.gameEvent(GameEvent.ENTITY_DIE);
-@@ -858,7 +898,12 @@ public class ServerPlayer extends Player {
+@@ -874,7 +914,12 @@ public class ServerPlayer extends Player {
this.dropExperience();
// we clean the player's inventory after the EntityDeathEvent is called so plugins can get the exact state of the inventory.
if (!event.getKeepInventory()) {
diff --git a/patches/server/0312-Optimize-Captured-TileEntity-Lookup.patch b/patches/server/0319-Optimize-Captured-TileEntity-Lookup.patch
index bddfd49587..bddfd49587 100644
--- a/patches/server/0312-Optimize-Captured-TileEntity-Lookup.patch
+++ b/patches/server/0319-Optimize-Captured-TileEntity-Lookup.patch
diff --git a/patches/server/0313-Add-Heightmap-API.patch b/patches/server/0320-Add-Heightmap-API.patch
index f4574ba880..6187c5d5d9 100644
--- a/patches/server/0313-Add-Heightmap-API.patch
+++ b/patches/server/0320-Add-Heightmap-API.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Add Heightmap API
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-index 4003325fa6d4e8391dd6496df620f29265fe1cf9..4687bbd141ace6e1ec3f4abf40b1cd559ae10987 100644
+index 3aa2e80e7d30d8824fd7f009282adfd8712cbb55..e43c68a086f1fcc6f7b3715bd55e75a64e4825de 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-@@ -223,6 +223,29 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+@@ -222,6 +222,29 @@ public class CraftWorld extends CraftRegionAccessor implements World {
return this.getHighestBlockYAt(x, z, org.bukkit.HeightMap.MOTION_BLOCKING);
}
diff --git a/patches/server/0314-Mob-Spawner-API-Enhancements.patch b/patches/server/0321-Mob-Spawner-API-Enhancements.patch
index 0947d35c6f..0947d35c6f 100644
--- a/patches/server/0314-Mob-Spawner-API-Enhancements.patch
+++ b/patches/server/0321-Mob-Spawner-API-Enhancements.patch
diff --git a/patches/server/0315-Fix-CB-call-to-changed-postToMainThread-method.patch b/patches/server/0322-Fix-CB-call-to-changed-postToMainThread-method.patch
index 97729ec723..97729ec723 100644
--- a/patches/server/0315-Fix-CB-call-to-changed-postToMainThread-method.patch
+++ b/patches/server/0322-Fix-CB-call-to-changed-postToMainThread-method.patch
diff --git a/patches/server/0316-Fix-sounds-when-item-frames-are-modified-MC-123450.patch b/patches/server/0323-Fix-sounds-when-item-frames-are-modified-MC-123450.patch
index 8f80e7c151..8f80e7c151 100644
--- a/patches/server/0316-Fix-sounds-when-item-frames-are-modified-MC-123450.patch
+++ b/patches/server/0323-Fix-sounds-when-item-frames-are-modified-MC-123450.patch
diff --git a/patches/server/0317-Fix-CraftServer-isPrimaryThread-and-MinecraftServer-.patch b/patches/server/0324-Fix-CraftServer-isPrimaryThread-and-MinecraftServer-.patch
index c8325ee866..c8325ee866 100644
--- a/patches/server/0317-Fix-CraftServer-isPrimaryThread-and-MinecraftServer-.patch
+++ b/patches/server/0324-Fix-CraftServer-isPrimaryThread-and-MinecraftServer-.patch
diff --git a/patches/server/0318-Implement-CraftBlockSoundGroup.patch b/patches/server/0325-Implement-CraftBlockSoundGroup.patch
index a62be7b054..a62be7b054 100644
--- a/patches/server/0318-Implement-CraftBlockSoundGroup.patch
+++ b/patches/server/0325-Implement-CraftBlockSoundGroup.patch
diff --git a/patches/server/0319-Configurable-Keep-Spawn-Loaded-range-per-world.patch b/patches/server/0326-Configurable-Keep-Spawn-Loaded-range-per-world.patch
index 0bf11f4945..9ead7ee244 100644
--- a/patches/server/0319-Configurable-Keep-Spawn-Loaded-range-per-world.patch
+++ b/patches/server/0326-Configurable-Keep-Spawn-Loaded-range-per-world.patch
@@ -6,7 +6,7 @@ Subject: [PATCH] Configurable Keep Spawn Loaded range per world
This lets you disable it for some worlds and lower it for others.
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
-index 49fe89baab93ae99a990684d78c5c05a223282c1..5cab48d7db58446310226acfae0dc3fcc1dba920 100644
+index f7d7e69e29f217c233869951d7d3188816f8216c..7342c8ac1d4bb13c0d8ce6f26b1b43d76a327655 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -729,31 +729,34 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -64,7 +64,7 @@ index 49fe89baab93ae99a990684d78c5c05a223282c1..5cab48d7db58446310226acfae0dc3fc
// CraftBukkit start
// this.updateMobSpawningFlags();
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index 6ba45e1322b0d04433b2aac23413a9cd10c0b4c0..7667c185178cf8cc15dd9c9b70402b1279e226a7 100644
+index 427dfb5c7fe09e94aae617ecc1440fd1530fb857..67a17a0fad369c412a943bb21b574c9cd5031fb8 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -64,6 +64,7 @@ import net.minecraft.network.protocol.game.ClientboundSoundEntityPacket;
@@ -75,7 +75,7 @@ index 6ba45e1322b0d04433b2aac23413a9cd10c0b4c0..7667c185178cf8cc15dd9c9b70402b12
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.ServerScoreboard;
import net.minecraft.server.level.progress.ChunkProgressListener;
-@@ -1714,12 +1715,84 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -1716,12 +1717,84 @@ public class ServerLevel extends Level implements WorldGenLevel {
return ((MapIndex) this.getServer().overworld().getDataStorage().computeIfAbsent(MapIndex::load, MapIndex::new, "idcounts")).getFreeAuxValueForMap();
}
@@ -200,10 +200,10 @@ index 4d2348df25410a0b5364eec066880326d6667dad..286aad3205ef8a9e21a47ef07893844f
this.maxCount = i * i;
}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-index 4687bbd141ace6e1ec3f4abf40b1cd559ae10987..2518674a967a5fbf2229a0fdd60447a62cfbf856 100644
+index e43c68a086f1fcc6f7b3715bd55e75a64e4825de..acfc8796a871706827f95c43f76b535e386d8daa 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-@@ -1357,15 +1357,21 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+@@ -1356,15 +1356,21 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@Override
public void setKeepSpawnInMemory(boolean keepLoaded) {
diff --git a/patches/server/0322-Allow-Saving-of-Oversized-Chunks.patch b/patches/server/0327-Allow-Saving-of-Oversized-Chunks.patch
index 0f82b9f323..04e29c57cc 100644
--- a/patches/server/0322-Allow-Saving-of-Oversized-Chunks.patch
+++ b/patches/server/0327-Allow-Saving-of-Oversized-Chunks.patch
@@ -142,7 +142,7 @@ index 038e2177182c94baa4af24f9111cf155ec342dfe..330fb8e6565a5c0490af0c5ca0e7355d
private final ChunkPos pos;
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
-index 9d7adf17851202adf03bf9feff3577069e324bc6..e734d82c2863caca8abc6bb8bb82882e971c36a8 100644
+index b790bb574546fef1969584529e49dbcf1403e198..ae1cb438cec25f8fef5dea0b2fddec6e72d5f26e 100644
--- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
@@ -11,8 +11,10 @@ import java.nio.file.Files;
diff --git a/patches/server/0323-Expose-the-internal-current-tick.patch b/patches/server/0328-Expose-the-internal-current-tick.patch
index 65596c8549..78a0152871 100644
--- a/patches/server/0323-Expose-the-internal-current-tick.patch
+++ b/patches/server/0328-Expose-the-internal-current-tick.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] Expose the internal current tick
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-index 0cc0435e53379208cc9c5f25ca185a26bd595caa..c125f4ba687d7622290da3f0e0fef5a8a859b4d2 100644
+index 2d6f8032cd5a5e7542a4a1cd791852873c93657e..e8c11b59dc50fd9c5bbf073b66d0cd9c504d7c25 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -2663,5 +2663,10 @@ public final class CraftServer implements Server {
diff --git a/patches/server/0324-Fix-World-isChunkGenerated-calls.patch b/patches/server/0329-Fix-World-isChunkGenerated-calls.patch
index dfb4fb11ef..c673732afb 100644
--- a/patches/server/0324-Fix-World-isChunkGenerated-calls.patch
+++ b/patches/server/0329-Fix-World-isChunkGenerated-calls.patch
@@ -8,10 +8,10 @@ This patch also adds a chunk status cache on region files (note that
its only purpose is to cache the status on DISK)
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
-index 47cb3be2d778a55bfbe733a9cc2965c8bf28a47a..33483dc272dbdee74767934f4b379a675162b7d1 100644
+index 8d0f7fb501aa5caa36b7dd273a8a7c7f959759cb..245f60eb904e26d6e7f7ca02bfa778d4f6db5d76 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
-@@ -1250,9 +1250,13 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -1354,9 +1354,13 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
// Paper end
private CompletableFuture<Optional<CompoundTag>> readChunk(ChunkPos chunkPos) {
@@ -28,7 +28,7 @@ index 47cb3be2d778a55bfbe733a9cc2965c8bf28a47a..33483dc272dbdee74767934f4b379a67
}
// CraftBukkit start
-@@ -1261,6 +1265,63 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -1365,6 +1369,63 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
// CraftBukkit end
}
@@ -188,7 +188,7 @@ index 330fb8e6565a5c0490af0c5ca0e7355d81a82e58..861a25a15f1aab20e3245b6d5cdad5d2
this.padToFullSector();
} finally {
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
-index e734d82c2863caca8abc6bb8bb82882e971c36a8..a96a6af2bcec3134b7caa32299bd07af50e83b89 100644
+index ae1cb438cec25f8fef5dea0b2fddec6e72d5f26e..2a6a4a62feb1c02bef850b0cda578f6f9d46a5e3 100644
--- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
@@ -245,6 +245,7 @@ public class RegionFileStorage implements AutoCloseable {
@@ -200,10 +200,10 @@ index e734d82c2863caca8abc6bb8bb82882e971c36a8..a96a6af2bcec3134b7caa32299bd07af
} catch (Throwable throwable) {
if (dataoutputstream != null) {
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-index 2518674a967a5fbf2229a0fdd60447a62cfbf856..cd70aa0fa7a575c3c1f6434db74c1cc8342fddb4 100644
+index acfc8796a871706827f95c43f76b535e386d8daa..868d9d13b03751b24c4b6695f97ad343ff8d0b8e 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-@@ -300,9 +300,23 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+@@ -299,9 +299,23 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@Override
public boolean isChunkGenerated(int x, int z) {
@@ -229,7 +229,7 @@ index 2518674a967a5fbf2229a0fdd60447a62cfbf856..cd70aa0fa7a575c3c1f6434db74c1cc8
throw new RuntimeException(ex);
}
}
-@@ -413,20 +427,48 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+@@ -412,20 +426,48 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@Override
public boolean loadChunk(int x, int z, boolean generate) {
org.spigotmc.AsyncCatcher.catchOp("chunk load"); // Spigot
diff --git a/patches/server/0325-Show-blockstate-location-if-we-failed-to-read-it.patch b/patches/server/0330-Show-blockstate-location-if-we-failed-to-read-it.patch
index f593178909..f593178909 100644
--- a/patches/server/0325-Show-blockstate-location-if-we-failed-to-read-it.patch
+++ b/patches/server/0330-Show-blockstate-location-if-we-failed-to-read-it.patch
diff --git a/patches/server/0326-Only-count-Natural-Spawned-mobs-towards-natural-spaw.patch b/patches/server/0331-Only-count-Natural-Spawned-mobs-towards-natural-spaw.patch
index a181d9b9ad..a181d9b9ad 100644
--- a/patches/server/0326-Only-count-Natural-Spawned-mobs-towards-natural-spaw.patch
+++ b/patches/server/0331-Only-count-Natural-Spawned-mobs-towards-natural-spaw.patch
diff --git a/patches/server/0327-Configurable-projectile-relative-velocity.patch b/patches/server/0332-Configurable-projectile-relative-velocity.patch
index 024876f999..024876f999 100644
--- a/patches/server/0327-Configurable-projectile-relative-velocity.patch
+++ b/patches/server/0332-Configurable-projectile-relative-velocity.patch
diff --git a/patches/server/0328-offset-item-frame-ticking.patch b/patches/server/0333-offset-item-frame-ticking.patch
index d20777b4c1..d20777b4c1 100644
--- a/patches/server/0328-offset-item-frame-ticking.patch
+++ b/patches/server/0333-offset-item-frame-ticking.patch
diff --git a/patches/server/0329-Fix-MC-158900.patch b/patches/server/0334-Fix-MC-158900.patch
index 2254e977c6..a2856aa25e 100644
--- a/patches/server/0329-Fix-MC-158900.patch
+++ b/patches/server/0334-Fix-MC-158900.patch
@@ -7,10 +7,10 @@ The problem was we were checking isExpired() on the entry, but if it
was expired at that point, then it would be null.
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
-index ee4d2f625629cf74f923592f11ecdb312de0c3ff..7ca5032574ddc4fb63dbf9ef266c71042055fb2a 100644
+index 3f95cfe7d6e85a19c4d6c4ce2b662a4259c45477..d362c9c83a73b5f49b54563b423c76c8ed78dfc6 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
-@@ -611,8 +611,10 @@ public abstract class PlayerList {
+@@ -612,8 +612,10 @@ public abstract class PlayerList {
Player player = entity.getBukkitEntity();
PlayerLoginEvent event = new PlayerLoginEvent(player, hostname, ((java.net.InetSocketAddress) socketaddress).getAddress(), ((java.net.InetSocketAddress) loginlistener.connection.getRawAddress()).getAddress());
diff --git a/patches/server/0330-Prevent-consuming-the-wrong-itemstack.patch b/patches/server/0335-Prevent-consuming-the-wrong-itemstack.patch
index 78e9ce8ae0..78e9ce8ae0 100644
--- a/patches/server/0330-Prevent-consuming-the-wrong-itemstack.patch
+++ b/patches/server/0335-Prevent-consuming-the-wrong-itemstack.patch
diff --git a/patches/server/0331-Dont-send-unnecessary-sign-update.patch b/patches/server/0336-Dont-send-unnecessary-sign-update.patch
index f99c1326eb..f99c1326eb 100644
--- a/patches/server/0331-Dont-send-unnecessary-sign-update.patch
+++ b/patches/server/0336-Dont-send-unnecessary-sign-update.patch
diff --git a/patches/server/0332-Add-option-to-disable-pillager-patrols.patch b/patches/server/0337-Add-option-to-disable-pillager-patrols.patch
index 65d645b929..65d645b929 100644
--- a/patches/server/0332-Add-option-to-disable-pillager-patrols.patch
+++ b/patches/server/0337-Add-option-to-disable-pillager-patrols.patch
diff --git a/patches/server/0333-Fix-AssertionError-when-player-hand-set-to-empty-typ.patch b/patches/server/0338-Fix-AssertionError-when-player-hand-set-to-empty-typ.patch
index e1945e2b80..e1945e2b80 100644
--- a/patches/server/0333-Fix-AssertionError-when-player-hand-set-to-empty-typ.patch
+++ b/patches/server/0338-Fix-AssertionError-when-player-hand-set-to-empty-typ.patch
diff --git a/patches/server/0334-Flat-bedrock-generator-settings.patch b/patches/server/0339-Flat-bedrock-generator-settings.patch
index 43ca0facd8..43ca0facd8 100644
--- a/patches/server/0334-Flat-bedrock-generator-settings.patch
+++ b/patches/server/0339-Flat-bedrock-generator-settings.patch
diff --git a/patches/server/0335-Prevent-sync-chunk-loads-when-villagers-try-to-find-.patch b/patches/server/0340-Prevent-sync-chunk-loads-when-villagers-try-to-find-.patch
index ea3c47b7b2..ea3c47b7b2 100644
--- a/patches/server/0335-Prevent-sync-chunk-loads-when-villagers-try-to-find-.patch
+++ b/patches/server/0340-Prevent-sync-chunk-loads-when-villagers-try-to-find-.patch
diff --git a/patches/server/0336-MC-145656-Fix-Follow-Range-Initial-Target.patch b/patches/server/0341-MC-145656-Fix-Follow-Range-Initial-Target.patch
index 44844fef0d..44844fef0d 100644
--- a/patches/server/0336-MC-145656-Fix-Follow-Range-Initial-Target.patch
+++ b/patches/server/0341-MC-145656-Fix-Follow-Range-Initial-Target.patch
diff --git a/patches/server/0337-Duplicate-UUID-Resolve-Option.patch b/patches/server/0342-Duplicate-UUID-Resolve-Option.patch
index 56ab60e5db..9c8f0336e7 100644
--- a/patches/server/0337-Duplicate-UUID-Resolve-Option.patch
+++ b/patches/server/0342-Duplicate-UUID-Resolve-Option.patch
@@ -32,11 +32,26 @@ But for those who are ok with leaving this inconsistent behavior, you may use WA
It is recommended you regenerate the entities, as these were legit entities, and deserve your love.
+diff --git a/src/main/java/net/minecraft/server/ChunkSystem.java b/src/main/java/net/minecraft/server/ChunkSystem.java
+index 1b1bfd5f92f85f46ad9661a0a64a2a1b4c33a80d..2a099fe0d514f181bf2b452d5333bc29b0d29e43 100644
+--- a/src/main/java/net/minecraft/server/ChunkSystem.java
++++ b/src/main/java/net/minecraft/server/ChunkSystem.java
+@@ -260,7 +260,9 @@ public final class ChunkSystem {
+ }
+
+ public static void onEntityPreAdd(final ServerLevel level, final Entity entity) {
+-
++ if (net.minecraft.server.level.ChunkMap.checkDupeUUID(level, entity)) {
++ return;
++ }
+ }
+
+ public static void onChunkHolderCreate(final ServerLevel level, final ChunkHolder holder) {
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
-index 33483dc272dbdee74767934f4b379a675162b7d1..eae2472f6dfd166cb457953ab396f85ca8c3f0f9 100644
+index 245f60eb904e26d6e7f7ca02bfa778d4f6db5d76..4b24e4d947e96ea0720f8f6bc33470e07c00310d 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
-@@ -878,6 +878,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -982,6 +982,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
entity.discard();
needsRemoval = true;
}
@@ -44,27 +59,32 @@ index 33483dc272dbdee74767934f4b379a675162b7d1..eae2472f6dfd166cb457953ab396f85c
return !needsRemoval;
}));
// CraftBukkit end
-@@ -928,6 +929,43 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -1032,6 +1033,49 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
});
}
+ // Paper start
-+ private static void checkDupeUUID(ServerLevel level, Entity entity) {
++ // rets true if to prevent the entity from being added
++ public static boolean checkDupeUUID(ServerLevel level, Entity entity) {
+ io.papermc.paper.configuration.WorldConfiguration.Entities.Spawning.DuplicateUUID.DuplicateUUIDMode mode = level.paperConfig().entities.spawning.duplicateUuid.mode;
+ if (mode != io.papermc.paper.configuration.WorldConfiguration.Entities.Spawning.DuplicateUUID.DuplicateUUIDMode.WARN
+ && mode != io.papermc.paper.configuration.WorldConfiguration.Entities.Spawning.DuplicateUUID.DuplicateUUIDMode.DELETE
+ && mode != io.papermc.paper.configuration.WorldConfiguration.Entities.Spawning.DuplicateUUID.DuplicateUUIDMode.SAFE_REGEN) {
-+ return;
++ return false;
+ }
+ Entity other = level.getEntity(entity.getUUID());
+
++ if (other == null || other == entity) {
++ return false;
++ }
++
+ if (mode == io.papermc.paper.configuration.WorldConfiguration.Entities.Spawning.DuplicateUUID.DuplicateUUIDMode.SAFE_REGEN && other != null && !other.isRemoved()
+ && Objects.equals(other.getEncodeId(), entity.getEncodeId())
+ && entity.getBukkitEntity().getLocation().distance(other.getBukkitEntity().getLocation()) < level.paperConfig().entities.spawning.duplicateUuid.safeRegenDeleteRange
+ ) {
+ if (ServerLevel.DEBUG_ENTITIES) LOGGER.warn("[DUPE-UUID] Duplicate UUID found used by " + other + ", deleted entity " + entity + " because it was near the duplicate and likely an actual duplicate. See https://github.com/PaperMC/Paper/issues/1223 for discussion on what this is about.");
+ entity.discard();
-+ return;
++ return true;
+ }
+ if (other != null && !other.isRemoved()) {
+ switch (mode) {
@@ -76,20 +96,21 @@ index 33483dc272dbdee74767934f4b379a675162b7d1..eae2472f6dfd166cb457953ab396f85c
+ case DELETE: {
+ if (ServerLevel.DEBUG_ENTITIES) LOGGER.warn("[DUPE-UUID] Duplicate UUID found used by " + other + ", deleted entity " + entity + ". See https://github.com/PaperMC/Paper/issues/1223 for discussion on what this is about.");
+ entity.discard();
-+ break;
++ return true;
+ }
+ default:
+ if (ServerLevel.DEBUG_ENTITIES) LOGGER.warn("[DUPE-UUID] Duplicate UUID found used by " + other + ", doing nothing to " + entity + ". See https://github.com/PaperMC/Paper/issues/1223 for discussion on what this is about.");
+ break;
+ }
+ }
++ return false;
+ }
+ // Paper end
public CompletableFuture<Either<LevelChunk, ChunkHolder.ChunkLoadingFailure>> prepareTickingChunk(ChunkHolder holder) {
ChunkPos chunkcoordintpair = holder.getPos();
CompletableFuture<Either<List<ChunkAccess>, ChunkHolder.ChunkLoadingFailure>> completablefuture = this.getChunkRangeFuture(chunkcoordintpair, 1, (i) -> {
diff --git a/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java b/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java
-index dfd1afc57664dd18c11f8a2547616074ccc55690..6e3d02fb68741fc3cf7d74ec659a37e5a1ecac5c 100644
+index ab7eadf2fc4c4598fa89068332eaaf9a8e0a100f..16519a6414f6f6418de40b714555a52631980617 100644
--- a/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java
+++ b/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java
@@ -78,7 +78,22 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
diff --git a/patches/server/0338-Optimize-Hoppers.patch b/patches/server/0343-Optimize-Hoppers.patch
index d598c74d04..7e66fc243d 100644
--- a/patches/server/0338-Optimize-Hoppers.patch
+++ b/patches/server/0343-Optimize-Hoppers.patch
@@ -13,7 +13,7 @@ Subject: [PATCH] Optimize Hoppers
* Remove Streams from Item Suck In and restore restore 1.12 AABB checks which is simpler and no voxel allocations (was doing TWO Item Suck ins)
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
-index 5cab48d7db58446310226acfae0dc3fcc1dba920..a02b674a925f2e070ed1bd203de262b513aae0a5 100644
+index 7342c8ac1d4bb13c0d8ce6f26b1b43d76a327655..3a085c141a5a6e2df9a85d0e3969363d69824294 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -1411,6 +1411,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
diff --git a/patches/server/0339-PlayerDeathEvent-shouldDropExperience.patch b/patches/server/0344-PlayerDeathEvent-shouldDropExperience.patch
index 96bde9d37a..f3bcd088d8 100644
--- a/patches/server/0339-PlayerDeathEvent-shouldDropExperience.patch
+++ b/patches/server/0344-PlayerDeathEvent-shouldDropExperience.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] PlayerDeathEvent#shouldDropExperience
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-index 02e81ba08b84f845b57a5148825ceb63313213a6..5dea577aeb4fa627e4c207b8a84933c1f2b63516 100644
+index d868c7f953cba9f7691c62edd2169ad26fc7d867..b36effc88b516958a7c0a46a7eb3a77a98ad3a20 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-@@ -895,7 +895,7 @@ public class ServerPlayer extends Player {
+@@ -911,7 +911,7 @@ public class ServerPlayer extends Player {
this.tellNeutralMobsThatIDied();
}
// SPIGOT-5478 must be called manually now
diff --git a/patches/server/0340-Prevent-bees-loading-chunks-checking-hive-position.patch b/patches/server/0345-Prevent-bees-loading-chunks-checking-hive-position.patch
index 3e8d451777..3e8d451777 100644
--- a/patches/server/0340-Prevent-bees-loading-chunks-checking-hive-position.patch
+++ b/patches/server/0345-Prevent-bees-loading-chunks-checking-hive-position.patch
diff --git a/patches/server/0341-Don-t-load-Chunks-from-Hoppers-and-other-things.patch b/patches/server/0346-Don-t-load-Chunks-from-Hoppers-and-other-things.patch
index 71f28eb22f..71f28eb22f 100644
--- a/patches/server/0341-Don-t-load-Chunks-from-Hoppers-and-other-things.patch
+++ b/patches/server/0346-Don-t-load-Chunks-from-Hoppers-and-other-things.patch
diff --git a/patches/server/0342-Guard-against-serializing-mismatching-chunk-coordina.patch b/patches/server/0347-Guard-against-serializing-mismatching-chunk-coordina.patch
index bc391d7a2a..bc391d7a2a 100644
--- a/patches/server/0342-Guard-against-serializing-mismatching-chunk-coordina.patch
+++ b/patches/server/0347-Guard-against-serializing-mismatching-chunk-coordina.patch
diff --git a/patches/server/0343-Optimise-IEntityAccess-getPlayerByUUID.patch b/patches/server/0348-Optimise-IEntityAccess-getPlayerByUUID.patch
index 7ee9512d04..3a47472ec8 100644
--- a/patches/server/0343-Optimise-IEntityAccess-getPlayerByUUID.patch
+++ b/patches/server/0348-Optimise-IEntityAccess-getPlayerByUUID.patch
@@ -6,10 +6,10 @@ Subject: [PATCH] Optimise IEntityAccess#getPlayerByUUID
Use the world entity map instead of iterating over all players
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index 7667c185178cf8cc15dd9c9b70402b1279e226a7..0cb83e84f8287bfaf170e78ed4cbce0ad00e3897 100644
+index 67a17a0fad369c412a943bb21b574c9cd5031fb8..3cf5ad6a77659073b740a2be3946a39c110dd4b8 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
-@@ -392,6 +392,14 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -394,6 +394,14 @@ public class ServerLevel extends Level implements WorldGenLevel {
public final com.destroystokyo.paper.io.chunk.ChunkTaskManager asyncChunkTaskManager;
// Paper end
diff --git a/patches/server/0344-Fix-items-not-falling-correctly.patch b/patches/server/0349-Fix-items-not-falling-correctly.patch
index 96b422d772..96b422d772 100644
--- a/patches/server/0344-Fix-items-not-falling-correctly.patch
+++ b/patches/server/0349-Fix-items-not-falling-correctly.patch
diff --git a/patches/server/0345-Lag-compensate-eating.patch b/patches/server/0350-Lag-compensate-eating.patch
index 5e5385d34c..5e5385d34c 100644
--- a/patches/server/0345-Lag-compensate-eating.patch
+++ b/patches/server/0350-Lag-compensate-eating.patch
diff --git a/patches/server/0346-Optimize-call-to-getFluid-for-explosions.patch b/patches/server/0351-Optimize-call-to-getFluid-for-explosions.patch
index 952f1fc45d..952f1fc45d 100644
--- a/patches/server/0346-Optimize-call-to-getFluid-for-explosions.patch
+++ b/patches/server/0351-Optimize-call-to-getFluid-for-explosions.patch
diff --git a/patches/server/0347-Fix-last-firework-in-stack-not-having-effects-when-d.patch b/patches/server/0352-Fix-last-firework-in-stack-not-having-effects-when-d.patch
index 448854642c..448854642c 100644
--- a/patches/server/0347-Fix-last-firework-in-stack-not-having-effects-when-d.patch
+++ b/patches/server/0352-Fix-last-firework-in-stack-not-having-effects-when-d.patch
diff --git a/patches/server/0348-Add-effect-to-block-break-naturally.patch b/patches/server/0353-Add-effect-to-block-break-naturally.patch
index b911824bb1..b911824bb1 100644
--- a/patches/server/0348-Add-effect-to-block-break-naturally.patch
+++ b/patches/server/0353-Add-effect-to-block-break-naturally.patch
diff --git a/patches/server/0349-Entity-Activation-Range-2.0.patch b/patches/server/0354-Entity-Activation-Range-2.0.patch
index 42ba15ee2c..9dcdbe0cef 100644
--- a/patches/server/0349-Entity-Activation-Range-2.0.patch
+++ b/patches/server/0354-Entity-Activation-Range-2.0.patch
@@ -14,7 +14,7 @@ Adds flying monsters to control ghast and phantoms
Adds villagers as separate config
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index 0cb83e84f8287bfaf170e78ed4cbce0ad00e3897..0013fdf7dd4074a9684eb4b93ea2735185c7ac1c 100644
+index 3cf5ad6a77659073b740a2be3946a39c110dd4b8..21fdca3b4bdc49d32deaf3f11d5fecc1ed0d4626 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -2,7 +2,6 @@ package net.minecraft.server.level;
@@ -25,7 +25,7 @@ index 0cb83e84f8287bfaf170e78ed4cbce0ad00e3897..0013fdf7dd4074a9684eb4b93ea27351
import com.google.common.collect.Lists;
import com.mojang.datafixers.DataFixer;
import com.mojang.datafixers.util.Pair;
-@@ -991,17 +990,17 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -993,17 +992,17 @@ public class ServerLevel extends Level implements WorldGenLevel {
++TimingHistory.entityTicks; // Paper - timings
// Spigot start
co.aikar.timings.Timing timer; // Paper
@@ -47,7 +47,7 @@ index 0cb83e84f8287bfaf170e78ed4cbce0ad00e3897..0013fdf7dd4074a9684eb4b93ea27351
try {
// Paper end - timings
entity.setOldPosAndRot();
-@@ -1012,9 +1011,13 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -1014,9 +1013,13 @@ public class ServerLevel extends Level implements WorldGenLevel {
return Registry.ENTITY_TYPE.getKey(entity.getType()).toString();
});
gameprofilerfiller.incrementCounter("tickNonPassenger");
@@ -61,7 +61,7 @@ index 0cb83e84f8287bfaf170e78ed4cbce0ad00e3897..0013fdf7dd4074a9684eb4b93ea27351
Iterator iterator = entity.getPassengers().iterator();
while (iterator.hasNext()) {
-@@ -1022,13 +1025,18 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -1024,13 +1027,18 @@ public class ServerLevel extends Level implements WorldGenLevel {
this.tickPassenger(entity, entity1);
}
@@ -81,7 +81,7 @@ index 0cb83e84f8287bfaf170e78ed4cbce0ad00e3897..0013fdf7dd4074a9684eb4b93ea27351
passenger.setOldPosAndRot();
++passenger.tickCount;
ProfilerFiller gameprofilerfiller = this.getProfiler();
-@@ -1037,8 +1045,17 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -1039,8 +1047,17 @@ public class ServerLevel extends Level implements WorldGenLevel {
return Registry.ENTITY_TYPE.getKey(passenger.getType()).toString();
});
gameprofilerfiller.incrementCounter("tickPassenger");
@@ -99,7 +99,7 @@ index 0cb83e84f8287bfaf170e78ed4cbce0ad00e3897..0013fdf7dd4074a9684eb4b93ea27351
gameprofilerfiller.pop();
Iterator iterator = passenger.getPassengers().iterator();
-@@ -1048,6 +1065,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -1050,6 +1067,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
this.tickPassenger(passenger, entity2);
}
@@ -108,7 +108,7 @@ index 0cb83e84f8287bfaf170e78ed4cbce0ad00e3897..0013fdf7dd4074a9684eb4b93ea27351
} else {
passenger.stopRiding();
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
-index 5f613eac047703b6f1521fcd2d802e381d5f42d5..a9f1b5fe81bef3e948d128598407d23c723fc075 100644
+index 482efc1c544cdd846f7330f4be43cc3e6eb397fc..022682dc729a2e595df09befc18d7d73143b7e74 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -384,6 +384,8 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
diff --git a/patches/server/0350-Increase-Light-Queue-Size.patch b/patches/server/0355-Increase-Light-Queue-Size.patch
index 5545385865..0c0b38a5fb 100644
--- a/patches/server/0350-Increase-Light-Queue-Size.patch
+++ b/patches/server/0355-Increase-Light-Queue-Size.patch
@@ -14,7 +14,7 @@ light engine on shutdown...
The queue size only puts a cap on max loss, doesn't solve that problem.
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
-index a02b674a925f2e070ed1bd203de262b513aae0a5..181e35da5919ba3b91246b427f2c5773acf1dd12 100644
+index 3a085c141a5a6e2df9a85d0e3969363d69824294..27f19abc22e295a5480dbed5df86f5d885ad3b73 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -780,7 +780,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
diff --git a/patches/server/0351-Fix-Light-Command.patch b/patches/server/0356-Fix-Light-Command.patch
index 9ddd1af8d2..a411a251f1 100644
--- a/patches/server/0351-Fix-Light-Command.patch
+++ b/patches/server/0356-Fix-Light-Command.patch
@@ -154,10 +154,10 @@ index 0000000000000000000000000000000000000000..190df802cb24aa360f6cf4d291e38b4b
+ }
+}
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
-index eae2472f6dfd166cb457953ab396f85ca8c3f0f9..8ab5fd86e626958646935e460b603c875b8a841b 100644
+index 4b24e4d947e96ea0720f8f6bc33470e07c00310d..d60173b03baee4a66da1109795bf6a19737b8bd0 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
-@@ -138,6 +138,12 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -141,6 +141,12 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
private final ChunkTaskPriorityQueueSorter queueSorter;
private final ProcessorHandle<ChunkTaskPriorityQueueSorter.Message<Runnable>> worldgenMailbox;
public final ProcessorHandle<ChunkTaskPriorityQueueSorter.Message<Runnable>> mainThreadMailbox;
@@ -170,7 +170,7 @@ index eae2472f6dfd166cb457953ab396f85ca8c3f0f9..8ab5fd86e626958646935e460b603c87
public final ChunkProgressListener progressListener;
private final ChunkStatusUpdateListener chunkStatusListener;
public final ChunkMap.ChunkDistanceManager distanceManager;
-@@ -261,11 +267,12 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -284,11 +290,12 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
this.progressListener = worldGenerationProgressListener;
this.chunkStatusListener = chunkStatusChangeListener;
diff --git a/patches/server/0352-Anti-Xray.patch b/patches/server/0357-Anti-Xray.patch
index 16d9b88b97..8e6fb2e557 100644
--- a/patches/server/0352-Anti-Xray.patch
+++ b/patches/server/0357-Anti-Xray.patch
@@ -1044,10 +1044,10 @@ index 7825d6f0fdcfda6212cff8033ec55fb7db236154..000853110c7a89f2d0403a7a2737025a
public ClientboundLevelChunkWithLightPacket(FriendlyByteBuf buf) {
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
-index 8ab5fd86e626958646935e460b603c875b8a841b..993a74bb16116622dc968f1f240fed1c377de5fa 100644
+index d60173b03baee4a66da1109795bf6a19737b8bd0..55a21a4024debc328d4829477d80c2998e291c22 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
-@@ -994,7 +994,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -1104,7 +1104,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
completablefuture1.thenAcceptAsync((either) -> {
either.ifLeft((chunk) -> {
this.tickingGenerated.getAndIncrement();
@@ -1056,7 +1056,7 @@ index 8ab5fd86e626958646935e460b603c875b8a841b..993a74bb16116622dc968f1f240fed1c
this.getPlayers(chunkcoordintpair, false).forEach((entityplayer) -> {
this.playerLoadedChunk(entityplayer, mutableobject, chunk);
-@@ -1173,7 +1173,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -1283,7 +1283,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
while (objectiterator.hasNext()) {
ChunkHolder playerchunk = (ChunkHolder) objectiterator.next();
ChunkPos chunkcoordintpair = playerchunk.getPos();
@@ -1065,7 +1065,7 @@ index 8ab5fd86e626958646935e460b603c875b8a841b..993a74bb16116622dc968f1f240fed1c
this.getPlayers(chunkcoordintpair, false).forEach((entityplayer) -> {
SectionPos sectionposition = entityplayer.getLastSectionPos();
-@@ -1187,7 +1187,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -1297,7 +1297,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
}
@@ -1074,7 +1074,7 @@ index 8ab5fd86e626958646935e460b603c875b8a841b..993a74bb16116622dc968f1f240fed1c
if (player.level == this.level) {
if (newWithinViewDistance && !oldWithinViewDistance) {
ChunkHolder playerchunk = this.getVisibleChunkIfPresent(pos.toLong());
-@@ -1724,12 +1724,17 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -1834,12 +1834,17 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
}
@@ -1097,10 +1097,10 @@ index 8ab5fd86e626958646935e460b603c875b8a841b..993a74bb16116622dc968f1f240fed1c
List<Entity> list = Lists.newArrayList();
List<Entity> list1 = Lists.newArrayList();
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index 0013fdf7dd4074a9684eb4b93ea2735185c7ac1c..fb7954d4d4dbd35bf771b362f241294d79cf9933 100644
+index 21fdca3b4bdc49d32deaf3f11d5fecc1ed0d4626..5622917a2884e87d43abfaf58e722957931b3178 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
-@@ -403,7 +403,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -405,7 +405,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
public ServerLevel(MinecraftServer minecraftserver, Executor executor, LevelStorageSource.LevelStorageAccess convertable_conversionsession, PrimaryLevelData iworlddataserver, ResourceKey<Level> resourcekey, LevelStem worlddimension, ChunkProgressListener worldloadlistener, boolean flag, long i, List<CustomSpawner> list, boolean flag1, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider) {
// Holder holder = worlddimension.typeHolder(); // CraftBukkit - decompile error
// Objects.requireNonNull(minecraftserver); // CraftBukkit - decompile error
@@ -1196,7 +1196,7 @@ index 6cec5cda20531aadf8e2148908a70f8b573d7d82..dc164608bfb2fb18a1adf83fa10bac40
}
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
-index e9fae214f60fe682087d41cfaa55a1b25e5f4331..ee7296eb561b59a4c0fce200f1a59f66a6526cc2 100644
+index e63086aba2512051fe1321f6e7e72b40276f5dde..004c8abeafa53cdc3efa0f45742132e3ad492d70 100644
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
@@ -93,7 +93,7 @@ public class LevelChunk extends ChunkAccess {
@@ -1551,7 +1551,7 @@ index cf48c93d89da53e0ec771e5c2c8582e30b35e3f5..518dfbb7dbd4221937636cf46d27109d
}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-index c125f4ba687d7622290da3f0e0fef5a8a859b4d2..3a183c9c85439d9595cc5667743cd7f41cc8c727 100644
+index e8c11b59dc50fd9c5bbf073b66d0cd9c504d7c25..8cc2a35486e8c6433e722ddc5e776c3332e7c7fe 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -2235,7 +2235,7 @@ public final class CraftServer implements Server {
@@ -1564,10 +1564,10 @@ index c125f4ba687d7622290da3f0e0fef5a8a859b4d2..3a183c9c85439d9595cc5667743cd7f4
@Override
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-index cd70aa0fa7a575c3c1f6434db74c1cc8342fddb4..21927118d1762302dc560b385fd3a4322840031f 100644
+index 868d9d13b03751b24c4b6695f97ad343ff8d0b8e..a8ab324bfbaaf946af5998402588244465dd7286 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-@@ -407,11 +407,16 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+@@ -406,11 +406,16 @@ public class CraftWorld extends CraftRegionAccessor implements World {
List<ServerPlayer> playersInRange = playerChunk.playerProvider.getPlayers(playerChunk.getPos(), false);
if (playersInRange.isEmpty()) return;
diff --git a/patches/server/0353-Implement-alternative-item-despawn-rate.patch b/patches/server/0358-Implement-alternative-item-despawn-rate.patch
index db8d53f699..db8d53f699 100644
--- a/patches/server/0353-Implement-alternative-item-despawn-rate.patch
+++ b/patches/server/0358-Implement-alternative-item-despawn-rate.patch
diff --git a/patches/server/0354-Tracking-Range-Improvements.patch b/patches/server/0359-Tracking-Range-Improvements.patch
index 035cfe82f8..53db6644cf 100644
--- a/patches/server/0354-Tracking-Range-Improvements.patch
+++ b/patches/server/0359-Tracking-Range-Improvements.patch
@@ -8,10 +8,10 @@ Sets tracking range of watermobs to animals instead of misc and simplifies code
Also ignores Enderdragon, defaulting it to Mojang's setting
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
-index 993a74bb16116622dc968f1f240fed1c377de5fa..1a06d0f8eedc4ef1e9a860c873aeff746669bfce 100644
+index 55a21a4024debc328d4829477d80c2998e291c22..0b68e6c7ef63460d596050ed55039a5ba3cefb24 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
-@@ -1912,6 +1912,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -2022,6 +2022,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
while (iterator.hasNext()) {
Entity entity = (Entity) iterator.next();
int j = entity.getType().clientTrackingRange() * 16;
diff --git a/patches/server/0355-Fix-items-vanishing-through-end-portal.patch b/patches/server/0360-Fix-items-vanishing-through-end-portal.patch
index a972dd7ef4..0ed6a4eaae 100644
--- a/patches/server/0355-Fix-items-vanishing-through-end-portal.patch
+++ b/patches/server/0360-Fix-items-vanishing-through-end-portal.patch
@@ -13,7 +13,7 @@ Quickly loading the exact world spawn chunk before searching the
heightmap resolves the issue without having to load all spawn chunks.
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
-index a9f1b5fe81bef3e948d128598407d23c723fc075..8576fbaedf3076e8b492c499d4176b1116e7ef56 100644
+index 022682dc729a2e595df09befc18d7d73143b7e74..240650cee26fc907f632e0c8ef3559a36460a3ba 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -3109,6 +3109,9 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
diff --git a/patches/server/0356-implement-optional-per-player-mob-spawns.patch b/patches/server/0361-implement-optional-per-player-mob-spawns.patch
index 64254218d1..804ad3cc57 100644
--- a/patches/server/0356-implement-optional-per-player-mob-spawns.patch
+++ b/patches/server/0361-implement-optional-per-player-mob-spawns.patch
@@ -252,10 +252,10 @@ index 0000000000000000000000000000000000000000..11de56afaf059b00fa5bec293516bcdc
+ }
+}
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
-index 1a06d0f8eedc4ef1e9a860c873aeff746669bfce..f20b93c6372e36016b21591d3cd63c5d7a47721e 100644
+index 0b68e6c7ef63460d596050ed55039a5ba3cefb24..9e940920f6ff6a43d7162d965936c171c55ed570 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
-@@ -156,6 +156,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -159,6 +159,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
private final Long2LongMap chunkSaveCooldowns;
private final Queue<Runnable> unloadQueue;
int viewDistance;
@@ -263,7 +263,7 @@ index 1a06d0f8eedc4ef1e9a860c873aeff746669bfce..f20b93c6372e36016b21591d3cd63c5d
// CraftBukkit start - recursion-safe executor for Chunk loadCallback() and unloadCallback()
public final CallbackExecutor callbackExecutor = new CallbackExecutor();
-@@ -185,16 +186,31 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -199,16 +200,31 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
int chunkX = MCUtil.getChunkCoordinate(player.getX());
int chunkZ = MCUtil.getChunkCoordinate(player.getZ());
// Note: players need to be explicitly added to distance maps before they can be updated
@@ -295,7 +295,7 @@ index 1a06d0f8eedc4ef1e9a860c873aeff746669bfce..f20b93c6372e36016b21591d3cd63c5d
}
// Paper end
// Paper start
-@@ -282,6 +298,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -305,6 +321,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
this.dataRegionManager = new io.papermc.paper.chunk.SingleThreadChunkRegionManager(this.level, 2, (1.0 / 3.0), 1, 6, "Data", DataRegionData::new, DataRegionSectionData::new);
this.regionManagers.add(this.dataRegionManager);
// Paper end
@@ -303,10 +303,10 @@ index 1a06d0f8eedc4ef1e9a860c873aeff746669bfce..f20b93c6372e36016b21591d3cd63c5d
}
protected ChunkGenerator generator() {
-@@ -303,6 +320,31 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
- });
+@@ -356,6 +373,30 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+ }
}
-
+ // Paper end
+ // Paper start
+ public void updatePlayerMobTypeMap(Entity entity) {
+ if (!this.level.paperConfig().entities.spawning.perPlayerMobSpawns) {
@@ -331,15 +331,14 @@ index 1a06d0f8eedc4ef1e9a860c873aeff746669bfce..f20b93c6372e36016b21591d3cd63c5d
+ return entityPlayer.mobCounts[mobCategory.ordinal()];
+ }
+ // Paper end
-+
+
private static double euclideanDistanceSquared(ChunkPos pos, Entity entity) {
double d0 = (double) SectionPos.sectionToBlockCoord(pos.x, 8);
- double d1 = (double) SectionPos.sectionToBlockCoord(pos.z, 8);
diff --git a/src/main/java/net/minecraft/server/level/DistanceManager.java b/src/main/java/net/minecraft/server/level/DistanceManager.java
-index 1e066a35b53b1f71a0e6376a22d51fc4c0a412dc..6228f2f67541da62b0ae093de987662db9643740 100644
+index b9b56068cdacd984f873cfb2a06a312e9912893d..9309ea89a440606be3e56ef634f5048a72b0009e 100644
--- a/src/main/java/net/minecraft/server/level/DistanceManager.java
+++ b/src/main/java/net/minecraft/server/level/DistanceManager.java
-@@ -326,6 +326,12 @@ public abstract class DistanceManager {
+@@ -466,6 +466,12 @@ public abstract class DistanceManager {
}
@@ -353,10 +352,10 @@ index 1e066a35b53b1f71a0e6376a22d51fc4c0a412dc..6228f2f67541da62b0ae093de987662d
this.naturalSpawnChunkCounter.runAllUpdates();
return this.naturalSpawnChunkCounter.chunks.size();
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
-index d66ec02b09bb7ae46aae8e55f00626139f074ae3..de5b80fce9757517e51f2ef55340e884f2d7e3d4 100644
+index f2775bc2c9137b7b81080f3113340923469bb46d..cd3de4cd1a38c5092f6a88de4fa33d6dda7f3445 100644
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
-@@ -908,7 +908,18 @@ public class ServerChunkCache extends ChunkSource {
+@@ -762,7 +762,18 @@ public class ServerChunkCache extends ChunkSource {
gameprofilerfiller.push("naturalSpawnCount");
this.level.timings.countNaturalMobs.startTiming(); // Paper - timings
int l = this.distanceManager.getNaturalSpawnChunkCount();
@@ -377,10 +376,10 @@ index d66ec02b09bb7ae46aae8e55f00626139f074ae3..de5b80fce9757517e51f2ef55340e884
this.lastSpawnState = spawnercreature_d;
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-index 5dea577aeb4fa627e4c207b8a84933c1f2b63516..1796e81889d62b691b7a709616ce08f155733597 100644
+index b36effc88b516958a7c0a46a7eb3a77a98ad3a20..582e08eaeee8fb6c777ad451ccc0436b02cac000 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-@@ -235,6 +235,11 @@ public class ServerPlayer extends Player {
+@@ -236,6 +236,11 @@ public class ServerPlayer extends Player {
public boolean queueHealthUpdatePacket = false;
public net.minecraft.network.protocol.game.ClientboundSetHealthPacket queuedHealthUpdatePacket;
// Paper end
@@ -392,14 +391,14 @@ index 5dea577aeb4fa627e4c207b8a84933c1f2b63516..1796e81889d62b691b7a709616ce08f1
// CraftBukkit start
public String displayName;
-@@ -325,6 +330,7 @@ public class ServerPlayer extends Player {
+@@ -326,6 +331,7 @@ public class ServerPlayer extends Player {
this.adventure$displayName = net.kyori.adventure.text.Component.text(this.getScoreboardName()); // Paper
this.bukkitPickUpLoot = true;
this.maxHealthCache = this.getMaxHealth();
+ this.cachedSingleMobDistanceMap = new com.destroystokyo.paper.util.PooledHashSets.PooledObjectLinkedOpenHashSet<>(this); // Paper
}
-
- // Yes, this doesn't match Vanilla, but it's the best we can do for now.
+ // Paper start - Chunk priority
+ public BlockPos getPointInFront(double inFront) {
diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java
index b4098068e674b639e82c07e5d60e4e2120b4305b..fa23e9c476d4edc6176d8b8a6cb13c52d2f66a87 100644
--- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java
diff --git a/patches/server/0357-Avoid-hopper-searches-if-there-are-no-items.patch b/patches/server/0362-Avoid-hopper-searches-if-there-are-no-items.patch
index 58fd30373e..58fd30373e 100644
--- a/patches/server/0357-Avoid-hopper-searches-if-there-are-no-items.patch
+++ b/patches/server/0362-Avoid-hopper-searches-if-there-are-no-items.patch
diff --git a/patches/server/0358-Bees-get-gravity-in-void.-Fixes-MC-167279.patch b/patches/server/0363-Bees-get-gravity-in-void.-Fixes-MC-167279.patch
index 2b398af935..2b398af935 100644
--- a/patches/server/0358-Bees-get-gravity-in-void.-Fixes-MC-167279.patch
+++ b/patches/server/0363-Bees-get-gravity-in-void.-Fixes-MC-167279.patch
diff --git a/patches/server/0359-Optimise-getChunkAt-calls-for-loaded-chunks.patch b/patches/server/0364-Optimise-getChunkAt-calls-for-loaded-chunks.patch
index 3831aba372..080f8f5b61 100644
--- a/patches/server/0359-Optimise-getChunkAt-calls-for-loaded-chunks.patch
+++ b/patches/server/0364-Optimise-getChunkAt-calls-for-loaded-chunks.patch
@@ -7,10 +7,10 @@ bypass the need to get a player chunk, then get the either,
then unwrap it...
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
-index de5b80fce9757517e51f2ef55340e884f2d7e3d4..c12c03b9e79f264ee593373f8a72ed37c0ae8514 100644
+index cd3de4cd1a38c5092f6a88de4fa33d6dda7f3445..9ef4a8dee2af8d76e5d2c27ff3490a394b9afd59 100644
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
-@@ -601,6 +601,12 @@ public class ServerChunkCache extends ChunkSource {
+@@ -442,6 +442,12 @@ public class ServerChunkCache extends ChunkSource {
return this.getChunk(x, z, leastStatus, create);
}, this.mainThreadProcessor).join();
} else {
@@ -23,7 +23,7 @@ index de5b80fce9757517e51f2ef55340e884f2d7e3d4..c12c03b9e79f264ee593373f8a72ed37
ProfilerFiller gameprofilerfiller = this.level.getProfiler();
gameprofilerfiller.incrementCounter("getChunk");
-@@ -652,39 +658,7 @@ public class ServerChunkCache extends ChunkSource {
+@@ -497,39 +503,7 @@ public class ServerChunkCache extends ChunkSource {
if (Thread.currentThread() != this.mainThread) {
return null;
} else {
diff --git a/patches/server/0360-Add-debug-for-sync-chunk-loads.patch b/patches/server/0365-Add-debug-for-sync-chunk-loads.patch
index 1ea33e7ff0..4657aa35a9 100644
--- a/patches/server/0360-Add-debug-for-sync-chunk-loads.patch
+++ b/patches/server/0365-Add-debug-for-sync-chunk-loads.patch
@@ -298,10 +298,10 @@ index 0000000000000000000000000000000000000000..1120aef5b0dd983c467167f77245884e
+ }
+}
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
-index c12c03b9e79f264ee593373f8a72ed37c0ae8514..509b2ee115584ce80717cc12a7ab548d103b4b92 100644
+index 9ef4a8dee2af8d76e5d2c27ff3490a394b9afd59..d97b50a7a71b8bb8dcaab35ae5f03314ad6acf7e 100644
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
-@@ -633,6 +633,7 @@ public class ServerChunkCache extends ChunkSource {
+@@ -476,6 +476,7 @@ public class ServerChunkCache extends ChunkSource {
this.level.asyncChunkTaskManager.raisePriority(x1, z1, com.destroystokyo.paper.io.PrioritizedTaskQueue.HIGHEST_PRIORITY);
com.destroystokyo.paper.io.chunk.ChunkTaskManager.pushChunkWait(this.level, x1, z1);
// Paper end
@@ -310,10 +310,10 @@ index c12c03b9e79f264ee593373f8a72ed37c0ae8514..509b2ee115584ce80717cc12a7ab548d
chunkproviderserver_b.managedBlock(completablefuture::isDone);
com.destroystokyo.paper.io.chunk.ChunkTaskManager.popChunkWait(); // Paper - async chunk debug
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index fb7954d4d4dbd35bf771b362f241294d79cf9933..8724396e7b2bb58b22c4f3262855f9f523dd6635 100644
+index 5622917a2884e87d43abfaf58e722957931b3178..ed8014ed36f8354aa1ae07689e9315c0c0d8867a 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
-@@ -390,6 +390,12 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -392,6 +392,12 @@ public class ServerLevel extends Level implements WorldGenLevel {
};
public final com.destroystokyo.paper.io.chunk.ChunkTaskManager asyncChunkTaskManager;
// Paper end
diff --git a/patches/server/0361-Remove-garbage-Java-version-check.patch b/patches/server/0366-Remove-garbage-Java-version-check.patch
index c878e14d14..c878e14d14 100644
--- a/patches/server/0361-Remove-garbage-Java-version-check.patch
+++ b/patches/server/0366-Remove-garbage-Java-version-check.patch
diff --git a/patches/server/0362-Add-ThrownEggHatchEvent.patch b/patches/server/0367-Add-ThrownEggHatchEvent.patch
index c026427598..c026427598 100644
--- a/patches/server/0362-Add-ThrownEggHatchEvent.patch
+++ b/patches/server/0367-Add-ThrownEggHatchEvent.patch
diff --git a/patches/server/0363-Entity-Jump-API.patch b/patches/server/0368-Entity-Jump-API.patch
index 13b50ec3de..13b50ec3de 100644
--- a/patches/server/0363-Entity-Jump-API.patch
+++ b/patches/server/0368-Entity-Jump-API.patch
diff --git a/patches/server/0364-Add-option-to-nerf-pigmen-from-nether-portals.patch b/patches/server/0369-Add-option-to-nerf-pigmen-from-nether-portals.patch
index e1e7b38b6d..8f2b02bbbc 100644
--- a/patches/server/0364-Add-option-to-nerf-pigmen-from-nether-portals.patch
+++ b/patches/server/0369-Add-option-to-nerf-pigmen-from-nether-portals.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] Add option to nerf pigmen from nether portals
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
-index 8576fbaedf3076e8b492c499d4176b1116e7ef56..8bdaee1054f64fa5a0f4058ac3dc7d3626138ac4 100644
+index 240650cee26fc907f632e0c8ef3559a36460a3ba..185f6dd93f325b638289acd723c6cbbbedac80e1 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -386,6 +386,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
diff --git a/patches/server/0365-Make-the-GUI-graph-fancier.patch b/patches/server/0370-Make-the-GUI-graph-fancier.patch
index b97ce20f84..b97ce20f84 100644
--- a/patches/server/0365-Make-the-GUI-graph-fancier.patch
+++ b/patches/server/0370-Make-the-GUI-graph-fancier.patch
diff --git a/patches/server/0366-add-hand-to-BlockMultiPlaceEvent.patch b/patches/server/0371-add-hand-to-BlockMultiPlaceEvent.patch
index 486014f2be..486014f2be 100644
--- a/patches/server/0366-add-hand-to-BlockMultiPlaceEvent.patch
+++ b/patches/server/0371-add-hand-to-BlockMultiPlaceEvent.patch
diff --git a/patches/server/0367-Validate-tripwire-hook-placement-before-update.patch b/patches/server/0372-Validate-tripwire-hook-placement-before-update.patch
index fd8a74807c..fd8a74807c 100644
--- a/patches/server/0367-Validate-tripwire-hook-placement-before-update.patch
+++ b/patches/server/0372-Validate-tripwire-hook-placement-before-update.patch
diff --git a/patches/server/0368-Add-option-to-allow-iron-golems-to-spawn-in-air.patch b/patches/server/0373-Add-option-to-allow-iron-golems-to-spawn-in-air.patch
index f058d157d0..f058d157d0 100644
--- a/patches/server/0368-Add-option-to-allow-iron-golems-to-spawn-in-air.patch
+++ b/patches/server/0373-Add-option-to-allow-iron-golems-to-spawn-in-air.patch
diff --git a/patches/server/0369-Configurable-chance-of-villager-zombie-infection.patch b/patches/server/0374-Configurable-chance-of-villager-zombie-infection.patch
index ce51b7964c..ce51b7964c 100644
--- a/patches/server/0369-Configurable-chance-of-villager-zombie-infection.patch
+++ b/patches/server/0374-Configurable-chance-of-villager-zombie-infection.patch
diff --git a/patches/server/0370-Optimise-Chunk-getFluid.patch b/patches/server/0375-Optimise-Chunk-getFluid.patch
index 14f1eb470a..670a1cca43 100644
--- a/patches/server/0370-Optimise-Chunk-getFluid.patch
+++ b/patches/server/0375-Optimise-Chunk-getFluid.patch
@@ -8,7 +8,7 @@ faster on its own, however removing the try catch makes it
easier to inline due to code size
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
-index ee7296eb561b59a4c0fce200f1a59f66a6526cc2..5f65aa89dfb21fced457a3a9fef6ba05385b6b76 100644
+index 004c8abeafa53cdc3efa0f45742132e3ad492d70..ebe17598d3ef17cc5f0e99b876ed67936d46060d 100644
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
@@ -381,18 +381,20 @@ public class LevelChunk extends ChunkAccess {
diff --git a/patches/server/0371-Set-spigots-verbose-world-setting-to-false-by-def.patch b/patches/server/0376-Set-spigots-verbose-world-setting-to-false-by-def.patch
index 45ea278818..45ea278818 100644
--- a/patches/server/0371-Set-spigots-verbose-world-setting-to-false-by-def.patch
+++ b/patches/server/0376-Set-spigots-verbose-world-setting-to-false-by-def.patch
diff --git a/patches/server/0372-Add-tick-times-API-and-mspt-command.patch b/patches/server/0377-Add-tick-times-API-and-mspt-command.patch
index b45a036e40..b45a036e40 100644
--- a/patches/server/0372-Add-tick-times-API-and-mspt-command.patch
+++ b/patches/server/0377-Add-tick-times-API-and-mspt-command.patch
diff --git a/patches/server/0373-Expose-MinecraftServer-isRunning.patch b/patches/server/0378-Expose-MinecraftServer-isRunning.patch
index 1cc90296d0..4bacea7d49 100644
--- a/patches/server/0373-Expose-MinecraftServer-isRunning.patch
+++ b/patches/server/0378-Expose-MinecraftServer-isRunning.patch
@@ -6,7 +6,7 @@ Subject: [PATCH] Expose MinecraftServer#isRunning
This allows for plugins to detect if the server is actually turning off in onDisable rather than just plugins reloading.
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-index 051853707609fc026ab49fcd4a5a3798cdbed94a..fc1ed21c74b12b77544455e3c04453e71409c2c2 100644
+index a6f40cba559a4ca8c91b4daca0867f3be9cc94e6..a35501ea43bf3589b346b1e684c318b44ca57977 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -2678,5 +2678,10 @@ public final class CraftServer implements Server {
diff --git a/patches/server/0374-Add-Raw-Byte-ItemStack-Serialization.patch b/patches/server/0379-Add-Raw-Byte-ItemStack-Serialization.patch
index fb799bc57d..fb799bc57d 100644
--- a/patches/server/0374-Add-Raw-Byte-ItemStack-Serialization.patch
+++ b/patches/server/0379-Add-Raw-Byte-ItemStack-Serialization.patch
diff --git a/patches/server/0375-Pillager-patrol-spawn-settings-and-per-player-option.patch b/patches/server/0380-Pillager-patrol-spawn-settings-and-per-player-option.patch
index 2caafe5a72..0b94225be1 100644
--- a/patches/server/0375-Pillager-patrol-spawn-settings-and-per-player-option.patch
+++ b/patches/server/0380-Pillager-patrol-spawn-settings-and-per-player-option.patch
@@ -10,10 +10,10 @@ When not per player it will use the Vanilla mechanic of one delay per
world and the world age for the start day.
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-index 1796e81889d62b691b7a709616ce08f155733597..84f68bb96eef7123cda3b096f992e4a2575fcd59 100644
+index 582e08eaeee8fb6c777ad451ccc0436b02cac000..71608048e941f83516631e2a3b6bf9f672d9f127 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-@@ -231,6 +231,7 @@ public class ServerPlayer extends Player {
+@@ -232,6 +232,7 @@ public class ServerPlayer extends Player {
public boolean wonGame;
private int containerUpdateDelay; // Paper
public long loginTime; // Paper
diff --git a/patches/server/0376-Remote-Connections-shouldn-t-hold-up-shutdown.patch b/patches/server/0381-Remote-Connections-shouldn-t-hold-up-shutdown.patch
index 74098cbac5..74098cbac5 100644
--- a/patches/server/0376-Remote-Connections-shouldn-t-hold-up-shutdown.patch
+++ b/patches/server/0381-Remote-Connections-shouldn-t-hold-up-shutdown.patch
diff --git a/patches/server/0377-Do-not-allow-bees-to-load-chunks-for-beehives.patch b/patches/server/0382-Do-not-allow-bees-to-load-chunks-for-beehives.patch
index aa61dfee66..aa61dfee66 100644
--- a/patches/server/0377-Do-not-allow-bees-to-load-chunks-for-beehives.patch
+++ b/patches/server/0382-Do-not-allow-bees-to-load-chunks-for-beehives.patch
diff --git a/patches/server/0378-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch b/patches/server/0383-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch
index a96e57c792..0fcb7a0f21 100644
--- a/patches/server/0378-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch
+++ b/patches/server/0383-Prevent-Double-PlayerChunkMap-adds-crashing-server.patch
@@ -7,10 +7,10 @@ Suspected case would be around the technique used in .stopRiding
Stack will identify any causer of this and warn instead of crashing.
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
-index f20b93c6372e36016b21591d3cd63c5d7a47721e..dab266e62f837e0efe57c0c4ae33b84c553c969c 100644
+index 9e940920f6ff6a43d7162d965936c171c55ed570..72af82374f47a1effc3d2f45beee1f611b4bb4b6 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
-@@ -1645,6 +1645,14 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -1754,6 +1754,14 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
public void addEntity(Entity entity) {
org.spigotmc.AsyncCatcher.catchOp("entity track"); // Spigot
@@ -26,10 +26,10 @@ index f20b93c6372e36016b21591d3cd63c5d7a47721e..dab266e62f837e0efe57c0c4ae33b84c
EntityType<?> entitytypes = entity.getType();
int i = entitytypes.clientTrackingRange() * 16;
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index 8724396e7b2bb58b22c4f3262855f9f523dd6635..e531c2ed2432b0184878cc3fcfe0bc91a551977c 100644
+index ed8014ed36f8354aa1ae07689e9315c0c0d8867a..f5a9edf47230a1552a36ee5de4cb7560ea9ba7c4 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
-@@ -2292,7 +2292,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -2294,7 +2294,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
public void onTrackingStart(Entity entity) {
org.spigotmc.AsyncCatcher.catchOp("entity register"); // Spigot
@@ -38,7 +38,7 @@ index 8724396e7b2bb58b22c4f3262855f9f523dd6635..e531c2ed2432b0184878cc3fcfe0bc91
if (entity instanceof ServerPlayer) {
ServerPlayer entityplayer = (ServerPlayer) entity;
-@@ -2326,6 +2326,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -2328,6 +2328,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
entity.updateDynamicGameEventListener(DynamicGameEventListener::add);
entity.valid = true; // CraftBukkit
diff --git a/patches/server/0379-Don-t-tick-dead-players.patch b/patches/server/0384-Don-t-tick-dead-players.patch
index f66cc88d98..183a646d3b 100644
--- a/patches/server/0379-Don-t-tick-dead-players.patch
+++ b/patches/server/0384-Don-t-tick-dead-players.patch
@@ -7,10 +7,10 @@ Causes sync chunk loads and who knows what all else.
This is safe because Spectators are skipped in unloaded chunks too in vanilla.
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-index 84f68bb96eef7123cda3b096f992e4a2575fcd59..0ad3dfc469145735f1669d4ca9a79f3fecc2ad60 100644
+index 71608048e941f83516631e2a3b6bf9f672d9f127..eae65f79bd1b286f35955bf7a0a5a116ecd12520 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-@@ -652,7 +652,7 @@ public class ServerPlayer extends Player {
+@@ -668,7 +668,7 @@ public class ServerPlayer extends Player {
public void doTick() {
try {
diff --git a/patches/server/0380-Dead-Player-s-shouldn-t-be-able-to-move.patch b/patches/server/0385-Dead-Player-s-shouldn-t-be-able-to-move.patch
index 83aebd18e6..83aebd18e6 100644
--- a/patches/server/0380-Dead-Player-s-shouldn-t-be-able-to-move.patch
+++ b/patches/server/0385-Dead-Player-s-shouldn-t-be-able-to-move.patch
diff --git a/patches/server/0381-Optimize-Collision-to-not-load-chunks.patch b/patches/server/0386-Optimize-Collision-to-not-load-chunks.patch
index 4b5ca48afb..df12155384 100644
--- a/patches/server/0381-Optimize-Collision-to-not-load-chunks.patch
+++ b/patches/server/0386-Optimize-Collision-to-not-load-chunks.patch
@@ -14,10 +14,10 @@ movement will load only the chunk the player enters anyways and avoids loading
massive amounts of surrounding chunks due to large AABB lookups.
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
-index 7ca5032574ddc4fb63dbf9ef266c71042055fb2a..bec8969cae05c895a001888d020d61fd2d82a788 100644
+index d362c9c83a73b5f49b54563b423c76c8ed78dfc6..256bd12178c8dca2889fbcedb9327cc4a1164cf5 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
-@@ -796,6 +796,7 @@ public abstract class PlayerList {
+@@ -797,6 +797,7 @@ public abstract class PlayerList {
entityplayer1.forceSetPositionRotation(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
// CraftBukkit end
@@ -26,7 +26,7 @@ index 7ca5032574ddc4fb63dbf9ef266c71042055fb2a..bec8969cae05c895a001888d020d61fd
entityplayer1.setPos(entityplayer1.getX(), entityplayer1.getY() + 1.0D, entityplayer1.getZ());
}
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
-index 8bdaee1054f64fa5a0f4058ac3dc7d3626138ac4..ccfb7dfe2327cd2e187ad7909342fc137fa126db 100644
+index 185f6dd93f325b638289acd723c6cbbbedac80e1..001c1d55218671eaa9cee28ae42d756f352ff2fa 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -236,6 +236,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
diff --git a/patches/server/0382-Don-t-move-existing-players-to-world-spawn.patch b/patches/server/0387-Don-t-move-existing-players-to-world-spawn.patch
index d3ff87a9bc..0464df901c 100644
--- a/patches/server/0382-Don-t-move-existing-players-to-world-spawn.patch
+++ b/patches/server/0387-Don-t-move-existing-players-to-world-spawn.patch
@@ -10,10 +10,10 @@ larger than the keep loaded range.
By skipping this, we avoid potential for a large spike on server start.
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-index 0ad3dfc469145735f1669d4ca9a79f3fecc2ad60..c2f9933796904628a55476eb9be1204b766893cf 100644
+index eae65f79bd1b286f35955bf7a0a5a116ecd12520..61f97fab1e0e3d6c9206c397cecfff868cf0d9d2 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-@@ -322,7 +322,7 @@ public class ServerPlayer extends Player {
+@@ -323,7 +323,7 @@ public class ServerPlayer extends Player {
this.stats = server.getPlayerList().getPlayerStats(this);
this.advancements = server.getPlayerList().getPlayerAdvancements(this);
this.maxUpStep = 1.0F;
@@ -22,7 +22,7 @@ index 0ad3dfc469145735f1669d4ca9a79f3fecc2ad60..c2f9933796904628a55476eb9be1204b
this.cachedSingleHashSet = new com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<>(this); // Paper
-@@ -540,7 +540,7 @@ public class ServerPlayer extends Player {
+@@ -556,7 +556,7 @@ public class ServerPlayer extends Player {
position = Vec3.atCenterOf(((ServerLevel) world).getSharedSpawnPos());
}
this.level = world;
@@ -32,10 +32,10 @@ index 0ad3dfc469145735f1669d4ca9a79f3fecc2ad60..c2f9933796904628a55476eb9be1204b
this.gameMode.setLevel((ServerLevel) world);
}
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
-index bec8969cae05c895a001888d020d61fd2d82a788..27dd95242c80d875de8f07e111f06e383eeec0d9 100644
+index 256bd12178c8dca2889fbcedb9327cc4a1164cf5..d9175bcd1060dbaee90e50466da3c6d816fb614e 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
-@@ -215,6 +215,8 @@ public abstract class PlayerList {
+@@ -216,6 +216,8 @@ public abstract class PlayerList {
worldserver1 = worldserver;
}
diff --git a/patches/server/0383-Optimize-GoalSelector-Goal.Flag-Set-operations.patch b/patches/server/0388-Optimize-GoalSelector-Goal.Flag-Set-operations.patch
index cf8d69b485..cf8d69b485 100644
--- a/patches/server/0383-Optimize-GoalSelector-Goal.Flag-Set-operations.patch
+++ b/patches/server/0388-Optimize-GoalSelector-Goal.Flag-Set-operations.patch
diff --git a/patches/server/0384-Improved-Watchdog-Support.patch b/patches/server/0389-Improved-Watchdog-Support.patch
index 4275ad252d..1ae35e0c51 100644
--- a/patches/server/0384-Improved-Watchdog-Support.patch
+++ b/patches/server/0389-Improved-Watchdog-Support.patch
@@ -269,10 +269,10 @@ index 637846c2dda1cf27c194ca4f16da454a62dc3f4b..648bc209938364a387c3f81dcd073db3
}
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
-index dab266e62f837e0efe57c0c4ae33b84c553c969c..48fc5d6ca854de036013586be634b3e05e2c52bc 100644
+index 72af82374f47a1effc3d2f45beee1f611b4bb4b6..fcc9dd6e1c54e4ca16102150aa4c12ecc7de06df 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
-@@ -589,6 +589,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -667,6 +667,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
MutableBoolean mutableboolean = new MutableBoolean();
do {
@@ -281,10 +281,10 @@ index dab266e62f837e0efe57c0c4ae33b84c553c969c..48fc5d6ca854de036013586be634b3e0
list.stream().map((playerchunk) -> {
CompletableFuture completablefuture;
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
-index 27dd95242c80d875de8f07e111f06e383eeec0d9..97c670508df6e5ee2a05a4765aafbeb23949b647 100644
+index d9175bcd1060dbaee90e50466da3c6d816fb614e..602a30f7dc51ffad9e5f5cc0b339108a2225aafd 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
-@@ -517,7 +517,7 @@ public abstract class PlayerList {
+@@ -518,7 +518,7 @@ public abstract class PlayerList {
this.cserver.getPluginManager().callEvent(playerQuitEvent);
entityplayer.getBukkitEntity().disconnect(playerQuitEvent.getQuitMessage());
@@ -318,10 +318,10 @@ index 11a02c8259a039bbe229c5626055bceef9308b5a..c488e069a19d4bf082c94032571fcc77
final String msg = String.format("Entity threw exception at %s:%s,%s,%s", entity.level.getWorld().getName(), entity.getX(), entity.getY(), entity.getZ());
MinecraftServer.LOGGER.error(msg, throwable);
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
-index 5f65aa89dfb21fced457a3a9fef6ba05385b6b76..291bcca206722c86bca6d13058d18c413c38d256 100644
+index ebe17598d3ef17cc5f0e99b876ed67936d46060d..c8444f4bfd127b7d8194aaa984505eff249ae094 100644
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
-@@ -1083,6 +1083,7 @@ public class LevelChunk extends ChunkAccess {
+@@ -1085,6 +1085,7 @@ public class LevelChunk extends ChunkAccess {
gameprofilerfiller.pop();
} catch (Throwable throwable) {
diff --git a/patches/server/0385-Optimize-Pathfinding.patch b/patches/server/0390-Optimize-Pathfinding.patch
index 061629eb03..061629eb03 100644
--- a/patches/server/0385-Optimize-Pathfinding.patch
+++ b/patches/server/0390-Optimize-Pathfinding.patch
diff --git a/patches/server/0386-Reduce-Either-Optional-allocation.patch b/patches/server/0391-Reduce-Either-Optional-allocation.patch
index 0f4641263b..0f4641263b 100644
--- a/patches/server/0386-Reduce-Either-Optional-allocation.patch
+++ b/patches/server/0391-Reduce-Either-Optional-allocation.patch
diff --git a/patches/server/0387-Reduce-memory-footprint-of-NBTTagCompound.patch b/patches/server/0392-Reduce-memory-footprint-of-NBTTagCompound.patch
index 740fcbecab..740fcbecab 100644
--- a/patches/server/0387-Reduce-memory-footprint-of-NBTTagCompound.patch
+++ b/patches/server/0392-Reduce-memory-footprint-of-NBTTagCompound.patch
diff --git a/patches/server/0388-Prevent-opening-inventories-when-frozen.patch b/patches/server/0393-Prevent-opening-inventories-when-frozen.patch
index 80482901c6..8c7b292e06 100644
--- a/patches/server/0388-Prevent-opening-inventories-when-frozen.patch
+++ b/patches/server/0393-Prevent-opening-inventories-when-frozen.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Prevent opening inventories when frozen
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-index c2f9933796904628a55476eb9be1204b766893cf..5e1bb276d61ed72027f94defc3f192756af5808f 100644
+index 61f97fab1e0e3d6c9206c397cecfff868cf0d9d2..227bcd9c1cfcc6bf8dedacdca28731a8ffc7171a 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-@@ -621,7 +621,7 @@ public class ServerPlayer extends Player {
+@@ -637,7 +637,7 @@ public class ServerPlayer extends Player {
containerUpdateDelay = level.paperConfig().tickRates.containerUpdate;
}
// Paper end
@@ -17,7 +17,7 @@ index c2f9933796904628a55476eb9be1204b766893cf..5e1bb276d61ed72027f94defc3f19275
this.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.CANT_USE); // Paper
this.containerMenu = this.inventoryMenu;
}
-@@ -1491,7 +1491,7 @@ public class ServerPlayer extends Player {
+@@ -1507,7 +1507,7 @@ public class ServerPlayer extends Player {
} else {
// CraftBukkit start
this.containerMenu = container;
diff --git a/patches/server/0389-Optimise-ArraySetSorted-removeIf.patch b/patches/server/0394-Optimise-ArraySetSorted-removeIf.patch
index 1aa31112c4..eed4ea8bc2 100644
--- a/patches/server/0389-Optimise-ArraySetSorted-removeIf.patch
+++ b/patches/server/0394-Optimise-ArraySetSorted-removeIf.patch
@@ -6,7 +6,7 @@ Subject: [PATCH] Optimise ArraySetSorted#removeIf
Remove iterator allocation and ensure the call is always O(n)
diff --git a/src/main/java/net/minecraft/server/level/DistanceManager.java b/src/main/java/net/minecraft/server/level/DistanceManager.java
-index 6228f2f67541da62b0ae093de987662db9643740..8376439e36f0f75779d0fbefbe50b215a40c42aa 100644
+index 9309ea89a440606be3e56ef634f5048a72b0009e..1d1ea158d095bb69260929e8d84f2632a875c136 100644
--- a/src/main/java/net/minecraft/server/level/DistanceManager.java
+++ b/src/main/java/net/minecraft/server/level/DistanceManager.java
@@ -86,13 +86,27 @@ public abstract class DistanceManager {
diff --git a/patches/server/0390-Don-t-run-entity-collision-code-if-not-needed.patch b/patches/server/0395-Don-t-run-entity-collision-code-if-not-needed.patch
index 17bc39fe8d..17bc39fe8d 100644
--- a/patches/server/0390-Don-t-run-entity-collision-code-if-not-needed.patch
+++ b/patches/server/0395-Don-t-run-entity-collision-code-if-not-needed.patch
diff --git a/patches/server/0391-Implement-Player-Client-Options-API.patch b/patches/server/0396-Implement-Player-Client-Options-API.patch
index 9b8bf897e3..5a4d2416f5 100644
--- a/patches/server/0391-Implement-Player-Client-Options-API.patch
+++ b/patches/server/0396-Implement-Player-Client-Options-API.patch
@@ -85,10 +85,10 @@ index 0000000000000000000000000000000000000000..b6f4400df3d8ec7e06a996de54f8cabb
+ }
+}
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-index 5e1bb276d61ed72027f94defc3f192756af5808f..2a18a60fdb71f1c665bda4a6c04a1fa1ff47a83b 100644
+index 227bcd9c1cfcc6bf8dedacdca28731a8ffc7171a..49cb507ddd378b9a16b82e5c2a28531fce9c6708 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-@@ -1855,6 +1855,7 @@ public class ServerPlayer extends Player {
+@@ -1871,6 +1871,7 @@ public class ServerPlayer extends Player {
public String locale = null; // CraftBukkit - add, lowercase // Paper - default to null
public java.util.Locale adventure$locale = java.util.Locale.US; // Paper
public void updateOptions(ServerboundClientInformationPacket packet) {
@@ -97,7 +97,7 @@ index 5e1bb276d61ed72027f94defc3f192756af5808f..2a18a60fdb71f1c665bda4a6c04a1fa1
if (getMainArm() != packet.mainHand()) {
PlayerChangedMainHandEvent event = new PlayerChangedMainHandEvent(this.getBukkitEntity(), getMainArm() == HumanoidArm.LEFT ? MainHand.LEFT : MainHand.RIGHT);
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
-index 8a349c179e9abcda140546c56ea884422b409b5d..71b96630dd6543d8a4d8df5165d7182fb0f35067 100644
+index 86447a824d9749f85a6378682d4a6f74ca19875d..0fda8c27c717bd030b826c5c7267b880f9d1f6b9 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -574,6 +574,24 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
diff --git a/patches/server/0392-Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch b/patches/server/0397-Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch
index fe3a5aca21..48eea37bf3 100644
--- a/patches/server/0392-Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch
+++ b/patches/server/0397-Don-t-crash-if-player-is-attempted-to-be-removed-fro.patch
@@ -7,10 +7,10 @@ Subject: [PATCH] Don't crash if player is attempted to be removed from
I suspect it deals with teleporting as it uses players current x/y/z
diff --git a/src/main/java/net/minecraft/server/level/DistanceManager.java b/src/main/java/net/minecraft/server/level/DistanceManager.java
-index 8376439e36f0f75779d0fbefbe50b215a40c42aa..4a9d0fca55b71f817defcb4286154c0a47bede03 100644
+index 1d1ea158d095bb69260929e8d84f2632a875c136..f456ba4bf699e1f6bd15726a037a0047b6ca7380 100644
--- a/src/main/java/net/minecraft/server/level/DistanceManager.java
+++ b/src/main/java/net/minecraft/server/level/DistanceManager.java
-@@ -300,8 +300,8 @@ public abstract class DistanceManager {
+@@ -440,8 +440,8 @@ public abstract class DistanceManager {
ObjectSet<ServerPlayer> objectset = (ObjectSet) this.playersPerChunk.get(i);
if (objectset == null) return; // CraftBukkit - SPIGOT-6208
diff --git a/patches/server/0393-Fix-Chunk-Post-Processing-deadlock-risk.patch b/patches/server/0398-Fix-Chunk-Post-Processing-deadlock-risk.patch
index d0b17eef56..91616ec7ae 100644
--- a/patches/server/0393-Fix-Chunk-Post-Processing-deadlock-risk.patch
+++ b/patches/server/0398-Fix-Chunk-Post-Processing-deadlock-risk.patch
@@ -25,10 +25,10 @@ This successfully fixed a reoccurring and highly reproducible crash
for heightmaps.
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
-index 48fc5d6ca854de036013586be634b3e05e2c52bc..0fdf33bfab3191dbb582bc401f6f0b62aadacb4e 100644
+index fcc9dd6e1c54e4ca16102150aa4c12ecc7de06df..aed3da6ef2d498d3f1c9c64177bf1ba6b8157493 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
-@@ -179,6 +179,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -193,6 +193,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
};
// CraftBukkit end
@@ -36,7 +36,7 @@ index 48fc5d6ca854de036013586be634b3e05e2c52bc..0fdf33bfab3191dbb582bc401f6f0b62
// Paper start - distance maps
private final com.destroystokyo.paper.util.misc.PooledLinkedHashSets<ServerPlayer> pooledLinkedPlayerHashSets = new com.destroystokyo.paper.util.misc.PooledLinkedHashSets<>();
-@@ -1023,16 +1024,15 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -1132,16 +1133,15 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
});
CompletableFuture<Either<LevelChunk, ChunkHolder.ChunkLoadingFailure>> completablefuture1 = completablefuture.thenApplyAsync((either) -> {
return either.mapLeft((list) -> {
@@ -60,10 +60,10 @@ index 48fc5d6ca854de036013586be634b3e05e2c52bc..0fdf33bfab3191dbb582bc401f6f0b62
completablefuture1.thenAcceptAsync((either) -> {
either.ifLeft((chunk) -> {
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
-index 509b2ee115584ce80717cc12a7ab548d103b4b92..42b4214a1319691e9a6cb0c5fafaeeff821f3f99 100644
+index d97b50a7a71b8bb8dcaab35ae5f03314ad6acf7e..a986051dead41f1a9f70e5e00572255e9939c4a9 100644
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
-@@ -1138,6 +1138,7 @@ public class ServerChunkCache extends ChunkSource {
+@@ -992,6 +992,7 @@ public class ServerChunkCache extends ChunkSource {
return super.pollTask() || execChunkTask; // Paper
}
} finally {
diff --git a/patches/server/0394-Fix-Longstanding-Broken-behavior-of-PlayerJoinEvent.patch b/patches/server/0399-Fix-Longstanding-Broken-behavior-of-PlayerJoinEvent.patch
index 1ba8c296be..de10cb2f1f 100644
--- a/patches/server/0394-Fix-Longstanding-Broken-behavior-of-PlayerJoinEvent.patch
+++ b/patches/server/0399-Fix-Longstanding-Broken-behavior-of-PlayerJoinEvent.patch
@@ -28,10 +28,10 @@ receives a deterministic result, and should no longer require 1 tick
delays anymore.
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
-index 0fdf33bfab3191dbb582bc401f6f0b62aadacb4e..5187988a22b55ac783147afe455a139662b67f7d 100644
+index aed3da6ef2d498d3f1c9c64177bf1ba6b8157493..ea224e68b680c5e9ab38998f7709a4dbe3471b86 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
-@@ -1653,6 +1653,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -1762,6 +1762,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
.printStackTrace();
return;
}
@@ -40,10 +40,10 @@ index 0fdf33bfab3191dbb582bc401f6f0b62aadacb4e..5187988a22b55ac783147afe455a1396
if (!(entity instanceof EnderDragonPart)) {
EntityType<?> entitytypes = entity.getType();
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-index 2a18a60fdb71f1c665bda4a6c04a1fa1ff47a83b..084521ed853fc2b15be355a17da8421c54716815 100644
+index 49cb507ddd378b9a16b82e5c2a28531fce9c6708..53dcb40f5217d560ee42da3d73d1e66e2620067a 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-@@ -254,6 +254,7 @@ public class ServerPlayer extends Player {
+@@ -255,6 +255,7 @@ public class ServerPlayer extends Player {
public double maxHealthCache;
public boolean joining = true;
public boolean sentListPacket = false;
@@ -52,10 +52,10 @@ index 2a18a60fdb71f1c665bda4a6c04a1fa1ff47a83b..084521ed853fc2b15be355a17da8421c
public String kickLeaveMessage = null; // SPIGOT-3034: Forward leave message to PlayerQuitEvent
// CraftBukkit end
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
-index 97c670508df6e5ee2a05a4765aafbeb23949b647..b48641bbe371ffacbbd659a0ee1783437267a4dc 100644
+index 602a30f7dc51ffad9e5f5cc0b339108a2225aafd..a7bc7e83b9355ef920d94fff8572528965352fb6 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
-@@ -281,6 +281,12 @@ public abstract class PlayerList {
+@@ -282,6 +282,12 @@ public abstract class PlayerList {
this.playersByUUID.put(player.getUUID(), player);
// this.broadcastAll(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER, new EntityPlayer[]{entityplayer})); // CraftBukkit - replaced with loop below
@@ -68,7 +68,7 @@ index 97c670508df6e5ee2a05a4765aafbeb23949b647..b48641bbe371ffacbbd659a0ee178343
// CraftBukkit start
CraftPlayer bukkitPlayer = player.getBukkitEntity();
-@@ -319,6 +325,8 @@ public abstract class PlayerList {
+@@ -320,6 +326,8 @@ public abstract class PlayerList {
player.connection.send(new ClientboundPlayerInfoPacket(ClientboundPlayerInfoPacket.Action.ADD_PLAYER, new ServerPlayer[]{entityplayer1}));
}
player.sentListPacket = true;
@@ -77,7 +77,7 @@ index 97c670508df6e5ee2a05a4765aafbeb23949b647..b48641bbe371ffacbbd659a0ee178343
// CraftBukkit end
player.connection.send(new ClientboundSetEntityDataPacket(player.getId(), player.getEntityData(), true)); // CraftBukkit - BungeeCord#2321, send complete data to self on spawn
-@@ -344,6 +352,11 @@ public abstract class PlayerList {
+@@ -345,6 +353,11 @@ public abstract class PlayerList {
playerconnection.send(new ClientboundUpdateMobEffectPacket(player.getId(), mobeffect));
}
@@ -89,7 +89,7 @@ index 97c670508df6e5ee2a05a4765aafbeb23949b647..b48641bbe371ffacbbd659a0ee178343
if (nbttagcompound != null && nbttagcompound.contains("RootVehicle", 10)) {
CompoundTag nbttagcompound1 = nbttagcompound.getCompound("RootVehicle");
// CraftBukkit start
-@@ -392,6 +405,10 @@ public abstract class PlayerList {
+@@ -393,6 +406,10 @@ public abstract class PlayerList {
}
}
@@ -100,7 +100,7 @@ index 97c670508df6e5ee2a05a4765aafbeb23949b647..b48641bbe371ffacbbd659a0ee178343
player.initInventoryMenu();
// CraftBukkit - Moved from above, added world
// Paper start - Add to collideRule team if needed
-@@ -401,6 +418,7 @@ public abstract class PlayerList {
+@@ -402,6 +419,7 @@ public abstract class PlayerList {
scoreboard.addPlayerToTeam(player.getScoreboardName(), collideRuleTeam);
}
// Paper end
diff --git a/patches/server/0395-Load-Chunks-for-Login-Asynchronously.patch b/patches/server/0400-Load-Chunks-for-Login-Asynchronously.patch
index 82b57d8902..8b3c658648 100644
--- a/patches/server/0395-Load-Chunks-for-Login-Asynchronously.patch
+++ b/patches/server/0400-Load-Chunks-for-Login-Asynchronously.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] Load Chunks for Login Asynchronously
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index 67f1a8490d48f55d58268d7e34a27170792b5559..a7db54a94a5017e737ce9682a52eed7405af8cc1 100644
+index f5a9edf47230a1552a36ee5de4cb7560ea9ba7c4..a778b4b5b2413c25c2f0f0efc72ba1d362d89acf 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -170,6 +170,7 @@ import org.bukkit.event.world.GenericGameEvent;
@@ -16,7 +16,7 @@ index 67f1a8490d48f55d58268d7e34a27170792b5559..a7db54a94a5017e737ce9682a52eed74
public class ServerLevel extends Level implements WorldGenLevel {
-@@ -404,6 +405,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -406,6 +407,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
return this.getServer().getPlayerList().getPlayer(uuid);
}
// Paper end
@@ -25,7 +25,7 @@ index 67f1a8490d48f55d58268d7e34a27170792b5559..a7db54a94a5017e737ce9682a52eed74
// Add env and gen to constructor, IWorldDataServer -> WorldDataServer
public ServerLevel(MinecraftServer minecraftserver, Executor executor, LevelStorageSource.LevelStorageAccess convertable_conversionsession, PrimaryLevelData iworlddataserver, ResourceKey<Level> resourcekey, LevelStem worlddimension, ChunkProgressListener worldloadlistener, boolean flag, long i, List<CustomSpawner> list, boolean flag1, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider) {
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-index 084521ed853fc2b15be355a17da8421c54716815..acc64abd9420b81ed4c8c17cf6a9f5bc5d35f116 100644
+index 53dcb40f5217d560ee42da3d73d1e66e2620067a..971f72c1dd713077c128279a78ed37f15aedeff6 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -182,6 +182,7 @@ public class ServerPlayer extends Player {
@@ -36,7 +36,7 @@ index 084521ed853fc2b15be355a17da8421c54716815..acc64abd9420b81ed4c8c17cf6a9f5bc
public final MinecraftServer server;
public final ServerPlayerGameMode gameMode;
private final PlayerAdvancements advancements;
-@@ -255,6 +256,7 @@ public class ServerPlayer extends Player {
+@@ -256,6 +257,7 @@ public class ServerPlayer extends Player {
public boolean joining = true;
public boolean sentListPacket = false;
public boolean supressTrackerForLogin = false; // Paper
@@ -45,10 +45,10 @@ index 084521ed853fc2b15be355a17da8421c54716815..acc64abd9420b81ed4c8c17cf6a9f5bc
public String kickLeaveMessage = null; // SPIGOT-3034: Forward leave message to PlayerQuitEvent
// CraftBukkit end
diff --git a/src/main/java/net/minecraft/server/level/TicketType.java b/src/main/java/net/minecraft/server/level/TicketType.java
-index be677d437d17b74c6188ce1bd5fc6fdc228fd92f..78fbb4c3e52e900956ae0811aaf934c81ee5ea48 100644
+index 478109526cff7ceb0565cea3b5e97b9a07fbf8d1..3c1698ba0d3bc412ab957777d9b5211dbc555208 100644
--- a/src/main/java/net/minecraft/server/level/TicketType.java
+++ b/src/main/java/net/minecraft/server/level/TicketType.java
-@@ -23,6 +23,7 @@ public class TicketType<T> {
+@@ -25,6 +25,7 @@ public class TicketType<T> {
public static final TicketType<ChunkPos> FORCED = TicketType.create("forced", Comparator.comparingLong(ChunkPos::toLong));
public static final TicketType<ChunkPos> LIGHT = TicketType.create("light", Comparator.comparingLong(ChunkPos::toLong));
public static final TicketType<BlockPos> PORTAL = TicketType.create("portal", Vec3i::compareTo, 300);
@@ -103,7 +103,7 @@ index c83395364edb4f2ba8515326b19c4f1a436a0502..c99266d4782c5d58339e63f7564c28b4
try {
ServerPlayer entityplayer1 = this.server.getPlayerList().getPlayerForLogin(this.gameProfile, s); // CraftBukkit - add player reference
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
-index b48641bbe371ffacbbd659a0ee1783437267a4dc..b1f6dc751c3dab5220a02223f6ba205aa0949f84 100644
+index a7bc7e83b9355ef920d94fff8572528965352fb6..32ab0cd6cb42b0ab8a14f790dfcf4b155c945d6d 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -139,6 +139,7 @@ public abstract class PlayerList {
@@ -114,19 +114,21 @@ index b48641bbe371ffacbbd659a0ee1783437267a4dc..b1f6dc751c3dab5220a02223f6ba205a
// CraftBukkit start
// private final Map<UUID, ServerStatisticManager> stats;
// private final Map<UUID, AdvancementDataPlayer> advancements;
-@@ -178,6 +179,11 @@ public abstract class PlayerList {
- }
-
+@@ -180,6 +181,13 @@ public abstract class PlayerList {
public void placeNewPlayer(Connection connection, ServerPlayer player) {
-+ ServerPlayer prev = pendingPlayers.put(player.getUUID(), player);// Paper
+ player.isRealPlayer = true; // Paper - Chunk priority
+ player.loginTime = System.currentTimeMillis(); // Paper
++ // Paper start
++ ServerPlayer prev = pendingPlayers.put(player.getUUID(), player);
+ if (prev != null) {
+ disconnectPendingPlayer(prev);
+ }
-+ player.networkManager = connection; // Paper
- player.loginTime = System.currentTimeMillis(); // Paper
++ player.networkManager = connection;
++ // Paper end
GameProfile gameprofile = player.getGameProfile();
GameProfileCache usercache = this.server.getProfileCache();
-@@ -191,7 +197,7 @@ public abstract class PlayerList {
+ Optional<GameProfile> optional = usercache.get(gameprofile.getId());
+@@ -192,7 +200,7 @@ public abstract class PlayerList {
if (nbttagcompound != null && nbttagcompound.contains("bukkit")) {
CompoundTag bukkit = nbttagcompound.getCompound("bukkit");
s = bukkit.contains("lastKnownName", 8) ? bukkit.getString("lastKnownName") : s;
@@ -135,7 +137,7 @@ index b48641bbe371ffacbbd659a0ee1783437267a4dc..b1f6dc751c3dab5220a02223f6ba205a
// CraftBukkit end
if (nbttagcompound != null) {
-@@ -218,11 +224,15 @@ public abstract class PlayerList {
+@@ -219,11 +227,15 @@ public abstract class PlayerList {
if (nbttagcompound == null) player.fudgeSpawnLocation(worldserver1); // Paper - only move to spawn on first login, otherwise, stay where you are....
player.setLevel(worldserver1);
@@ -152,7 +154,7 @@ index b48641bbe371ffacbbd659a0ee1783437267a4dc..b1f6dc751c3dab5220a02223f6ba205a
// Spigot start - spawn location event
Player spawnPlayer = player.getBukkitEntity();
-@@ -264,6 +274,61 @@ public abstract class PlayerList {
+@@ -265,6 +277,56 @@ public abstract class PlayerList {
player.getRecipeBook().sendInitialRecipeBook(player);
this.updateEntireScoreboard(worldserver1.getScoreboard(), player);
this.server.invalidateStatus();
@@ -164,31 +166,26 @@ index b48641bbe371ffacbbd659a0ee1783437267a4dc..b1f6dc751c3dab5220a02223f6ba205a
+ final net.minecraft.world.level.ChunkPos pos = new net.minecraft.world.level.ChunkPos(chunkX, chunkZ);
+ net.minecraft.server.level.ChunkMap playerChunkMap = worldserver1.getChunkSource().chunkMap;
+ net.minecraft.server.level.DistanceManager distanceManager = playerChunkMap.distanceManager;
-+ distanceManager.addTicket(net.minecraft.server.level.TicketType.LOGIN, pos, 31, pos.toLong());
-+ worldserver1.getChunkSource().runDistanceManagerUpdates();
-+ worldserver1.getChunkSource().getChunkAtAsynchronously(chunkX, chunkZ, true, true).thenApply(chunk -> {
-+ net.minecraft.server.level.ChunkHolder updatingChunk = playerChunkMap.getUpdatingChunkIfPresent(pos.toLong());
-+ if (updatingChunk != null) {
-+ return updatingChunk.getEntityTickingChunkFuture();
-+ } else {
-+ return java.util.concurrent.CompletableFuture.completedFuture(chunk);
-+ }
-+ }).thenAccept(chunk -> {
-+ MinecraftServer.getServer().scheduleOnMain(() -> {
-+ try {
-+ if (!playerconnection.connection.isConnected()) {
-+ return;
++ net.minecraft.server.ChunkSystem.scheduleTickingState(
++ worldserver1, chunkX, chunkZ, net.minecraft.server.level.ChunkHolder.FullChunkStatus.ENTITY_TICKING, true,
++ ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority.HIGHEST,
++ (chunk) -> {
++ MinecraftServer.getServer().scheduleOnMain(() -> {
++ try {
++ if (!playerconnection.connection.isConnected()) {
++ return;
++ }
++ PlayerList.this.postChunkLoadJoin(
++ player, finalWorldserver, connection, playerconnection,
++ nbttagcompound, s1, lastKnownName
++ );
++ distanceManager.addTicket(net.minecraft.server.level.TicketType.LOGIN, pos, 31, pos.toLong());
++ } finally {
++ finalWorldserver.pendingLogin.remove(player);
+ }
-+ PlayerList.this.postChunkLoadJoin(
-+ player, finalWorldserver, connection, playerconnection,
-+ nbttagcompound, s1, lastKnownName
-+ );
-+ distanceManager.addTicket(net.minecraft.server.level.TicketType.LOGIN, pos, 31, pos.toLong());
-+ } finally {
-+ finalWorldserver.pendingLogin.remove(player);
-+ }
-+ });
-+ });
++ });
++ }
++ );
+ }
+
+ public ServerPlayer getActivePlayer(UUID uuid) {
@@ -214,7 +211,7 @@ index b48641bbe371ffacbbd659a0ee1783437267a4dc..b1f6dc751c3dab5220a02223f6ba205a
MutableComponent ichatmutablecomponent;
if (player.getGameProfile().getName().equalsIgnoreCase(s)) {
-@@ -505,6 +570,7 @@ public abstract class PlayerList {
+@@ -506,6 +568,7 @@ public abstract class PlayerList {
protected void save(ServerPlayer player) {
if (!player.getBukkitEntity().isPersistent()) return; // CraftBukkit
@@ -222,7 +219,7 @@ index b48641bbe371ffacbbd659a0ee1783437267a4dc..b1f6dc751c3dab5220a02223f6ba205a
this.playerIo.save(player);
ServerStatsCounter serverstatisticmanager = (ServerStatsCounter) player.getStats(); // CraftBukkit
-@@ -532,7 +598,7 @@ public abstract class PlayerList {
+@@ -533,7 +596,7 @@ public abstract class PlayerList {
}
PlayerQuitEvent playerQuitEvent = new PlayerQuitEvent(entityplayer.getBukkitEntity(), net.kyori.adventure.text.Component.translatable("multiplayer.player.left", net.kyori.adventure.text.format.NamedTextColor.YELLOW, io.papermc.paper.configuration.GlobalConfiguration.get().messages.useDisplayNameInQuitMessage ? entityplayer.getBukkitEntity().displayName() : net.kyori.adventure.text.Component.text(entityplayer.getScoreboardName())));
@@ -231,7 +228,7 @@ index b48641bbe371ffacbbd659a0ee1783437267a4dc..b1f6dc751c3dab5220a02223f6ba205a
entityplayer.getBukkitEntity().disconnect(playerQuitEvent.getQuitMessage());
if (server.isSameThread()) entityplayer.doTick(); // SPIGOT-924 // Paper - don't tick during emergency shutdowns (Watchdog)
-@@ -577,6 +643,13 @@ public abstract class PlayerList {
+@@ -578,6 +641,13 @@ public abstract class PlayerList {
// this.advancements.remove(uuid);
// CraftBukkit end
}
@@ -245,7 +242,7 @@ index b48641bbe371ffacbbd659a0ee1783437267a4dc..b1f6dc751c3dab5220a02223f6ba205a
// CraftBukkit start
// this.broadcastAll(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.REMOVE_PLAYER, new EntityPlayer[]{entityplayer}));
-@@ -594,7 +667,7 @@ public abstract class PlayerList {
+@@ -595,7 +665,7 @@ public abstract class PlayerList {
this.cserver.getScoreboardManager().removePlayer(entityplayer.getBukkitEntity());
// CraftBukkit end
@@ -254,7 +251,7 @@ index b48641bbe371ffacbbd659a0ee1783437267a4dc..b1f6dc751c3dab5220a02223f6ba205a
}
// CraftBukkit start - Whole method, SocketAddress to LoginListener, added hostname to signature, return EntityPlayer
-@@ -613,6 +686,13 @@ public abstract class PlayerList {
+@@ -614,6 +684,13 @@ public abstract class PlayerList {
list.add(entityplayer);
}
}
diff --git a/patches/server/0396-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch b/patches/server/0401-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch
index 70e92d4754..0a1150e1ea 100644
--- a/patches/server/0396-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch
+++ b/patches/server/0401-Move-player-to-spawn-point-if-spawn-in-unloaded-worl.patch
@@ -7,7 +7,7 @@ The code following this has better support for null worlds to move
them back to the world spawn.
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
-index ccfb7dfe2327cd2e187ad7909342fc137fa126db..15c551347badbd0177d57c2b7d3500006eb7e0f7 100644
+index 001c1d55218671eaa9cee28ae42d756f352ff2fa..1b8f7bd5dd85136788b02cef64353d581cdf2108 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -2096,9 +2096,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
diff --git a/patches/server/0397-Add-PlayerAttackEntityCooldownResetEvent.patch b/patches/server/0402-Add-PlayerAttackEntityCooldownResetEvent.patch
index 98d462b590..98d462b590 100644
--- a/patches/server/0397-Add-PlayerAttackEntityCooldownResetEvent.patch
+++ b/patches/server/0402-Add-PlayerAttackEntityCooldownResetEvent.patch
diff --git a/patches/server/0398-Don-t-fire-BlockFade-on-worldgen-threads.patch b/patches/server/0403-Don-t-fire-BlockFade-on-worldgen-threads.patch
index b9aecc5313..b9aecc5313 100644
--- a/patches/server/0398-Don-t-fire-BlockFade-on-worldgen-threads.patch
+++ b/patches/server/0403-Don-t-fire-BlockFade-on-worldgen-threads.patch
diff --git a/patches/server/0399-Add-phantom-creative-and-insomniac-controls.patch b/patches/server/0404-Add-phantom-creative-and-insomniac-controls.patch
index 3b9eaafdbf..3b9eaafdbf 100644
--- a/patches/server/0399-Add-phantom-creative-and-insomniac-controls.patch
+++ b/patches/server/0404-Add-phantom-creative-and-insomniac-controls.patch
diff --git a/patches/server/0400-Fix-numerous-item-duplication-issues-and-teleport-is.patch b/patches/server/0405-Fix-numerous-item-duplication-issues-and-teleport-is.patch
index ffa011ceed..e5cb8f7d91 100644
--- a/patches/server/0400-Fix-numerous-item-duplication-issues-and-teleport-is.patch
+++ b/patches/server/0405-Fix-numerous-item-duplication-issues-and-teleport-is.patch
@@ -16,7 +16,7 @@ So even if something NEW comes up, it would be impossible to drop the
same item twice because the source was destroyed.
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
-index 15c551347badbd0177d57c2b7d3500006eb7e0f7..70978ba28cec4dd3e64bf380c0669b3bcf4a640b 100644
+index 1b8f7bd5dd85136788b02cef64353d581cdf2108..74e13ae8b1e6a9365d46f5684ee58e42658d2341 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -2226,11 +2226,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
diff --git a/patches/server/0401-Villager-Restocks-API.patch b/patches/server/0406-Villager-Restocks-API.patch
index d4af2305a8..d4af2305a8 100644
--- a/patches/server/0401-Villager-Restocks-API.patch
+++ b/patches/server/0406-Villager-Restocks-API.patch
diff --git a/patches/server/0402-Validate-PickItem-Packet-and-kick-for-invalid.patch b/patches/server/0407-Validate-PickItem-Packet-and-kick-for-invalid.patch
index 73612dfd5b..73612dfd5b 100644
--- a/patches/server/0402-Validate-PickItem-Packet-and-kick-for-invalid.patch
+++ b/patches/server/0407-Validate-PickItem-Packet-and-kick-for-invalid.patch
diff --git a/patches/server/0403-Expose-game-version.patch b/patches/server/0408-Expose-game-version.patch
index 82cea73f25..ba5a794206 100644
--- a/patches/server/0403-Expose-game-version.patch
+++ b/patches/server/0408-Expose-game-version.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] Expose game version
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-index bfd785af2d459061054a101def1a6c6bfd9cdda1..ed74a0295d3ade16cd3120ef6abc391f662b1263 100644
+index c8c11ec3c5c4c4d1ed09163aa6d3a4275e497e11..aac16630c83034cdb1ce14e04bfc24c39ff65454 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -579,6 +579,13 @@ public final class CraftServer implements Server {
diff --git a/patches/server/0404-Optimize-Voxel-Shape-Merging.patch b/patches/server/0409-Optimize-Voxel-Shape-Merging.patch
index 7bfe849396..7bfe849396 100644
--- a/patches/server/0404-Optimize-Voxel-Shape-Merging.patch
+++ b/patches/server/0409-Optimize-Voxel-Shape-Merging.patch
diff --git a/patches/server/0405-Set-cap-on-JDK-per-thread-native-byte-buffer-cache.patch b/patches/server/0410-Set-cap-on-JDK-per-thread-native-byte-buffer-cache.patch
index 6c54f83680..6c54f83680 100644
--- a/patches/server/0405-Set-cap-on-JDK-per-thread-native-byte-buffer-cache.patch
+++ b/patches/server/0410-Set-cap-on-JDK-per-thread-native-byte-buffer-cache.patch
diff --git a/patches/server/0406-misc-debugging-dumps.patch b/patches/server/0411-misc-debugging-dumps.patch
index 1471756c75..1709001c6e 100644
--- a/patches/server/0406-misc-debugging-dumps.patch
+++ b/patches/server/0411-misc-debugging-dumps.patch
@@ -29,7 +29,7 @@ index 0000000000000000000000000000000000000000..2d5494d2813b773e60ddba6790b750a9
+ }
+}
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
-index 40945909bbefa59da6be784bcf440dfb2075b670..b1f8374253d04d1468f5d57792b30f91a274b97f 100644
+index 3a4222f78a02e10ecccc03df3c580895fbb8059d..ff94b07246b5e17be53f4e7294557c6744c62248 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -871,6 +871,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -74,7 +74,7 @@ index c99266d4782c5d58339e63f7564c28b4b5b7ac1d..d477e9fbe6ffb600d08f8ba49741067d
this.connection.send(new ClientboundDisconnectPacket(ichatmutablecomponent));
this.connection.disconnect(ichatmutablecomponent);
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-index ed74a0295d3ade16cd3120ef6abc391f662b1263..8d0a4c3e7fc49bac8af97e8a086f7c12ce874f86 100644
+index aac16630c83034cdb1ce14e04bfc24c39ff65454..4870a16251def58c8259d6f63b3ef6b91687665d 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -1002,6 +1002,7 @@ public final class CraftServer implements Server {
diff --git a/patches/server/0407-Prevent-teleporting-dead-entities.patch b/patches/server/0412-Prevent-teleporting-dead-entities.patch
index 526b593a85..526b593a85 100644
--- a/patches/server/0407-Prevent-teleporting-dead-entities.patch
+++ b/patches/server/0412-Prevent-teleporting-dead-entities.patch
diff --git a/patches/server/0408-Deobfuscate-stacktraces-in-log-messages-crash-report.patch b/patches/server/0413-Deobfuscate-stacktraces-in-log-messages-crash-report.patch
index 3f3a055bc6..3f3a055bc6 100644
--- a/patches/server/0408-Deobfuscate-stacktraces-in-log-messages-crash-report.patch
+++ b/patches/server/0413-Deobfuscate-stacktraces-in-log-messages-crash-report.patch
diff --git a/patches/server/0409-Implement-Mob-Goal-API.patch b/patches/server/0414-Implement-Mob-Goal-API.patch
index 954ff6a36b..f8748925df 100644
--- a/patches/server/0409-Implement-Mob-Goal-API.patch
+++ b/patches/server/0414-Implement-Mob-Goal-API.patch
@@ -789,7 +789,7 @@ index 4379b9948f1eecfe6fd7dea98e298ad5f761019a..3f081183521603824430709886a9cc31
LOOK,
JUMP,
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-index 8d0a4c3e7fc49bac8af97e8a086f7c12ce874f86..5ac4ff48b631649eac804553faf67330e9827806 100644
+index 4870a16251def58c8259d6f63b3ef6b91687665d..6e4d06e0eadf3b97a3fa2b8b8499ce30335a4fff 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -2691,5 +2691,11 @@ public final class CraftServer implements Server {
diff --git a/patches/server/0410-Add-villager-reputation-API.patch b/patches/server/0415-Add-villager-reputation-API.patch
index 4c38780334..4c38780334 100644
--- a/patches/server/0410-Add-villager-reputation-API.patch
+++ b/patches/server/0415-Add-villager-reputation-API.patch
diff --git a/patches/server/0411-Option-for-maximum-exp-value-when-merging-orbs.patch b/patches/server/0416-Option-for-maximum-exp-value-when-merging-orbs.patch
index 4239e066f4..4239e066f4 100644
--- a/patches/server/0411-Option-for-maximum-exp-value-when-merging-orbs.patch
+++ b/patches/server/0416-Option-for-maximum-exp-value-when-merging-orbs.patch
diff --git a/patches/server/0412-ExperienceOrbMergeEvent.patch b/patches/server/0417-ExperienceOrbMergeEvent.patch
index 1ff06b6779..1ff06b6779 100644
--- a/patches/server/0412-ExperienceOrbMergeEvent.patch
+++ b/patches/server/0417-ExperienceOrbMergeEvent.patch
diff --git a/patches/server/0413-Fix-PotionEffect-ignores-icon-flag.patch b/patches/server/0418-Fix-PotionEffect-ignores-icon-flag.patch
index e542865e62..e542865e62 100644
--- a/patches/server/0413-Fix-PotionEffect-ignores-icon-flag.patch
+++ b/patches/server/0418-Fix-PotionEffect-ignores-icon-flag.patch
diff --git a/patches/server/0414-Optimize-brigadier-child-sorting-performance.patch b/patches/server/0419-Optimize-brigadier-child-sorting-performance.patch
index 3651f34b15..3651f34b15 100644
--- a/patches/server/0414-Optimize-brigadier-child-sorting-performance.patch
+++ b/patches/server/0419-Optimize-brigadier-child-sorting-performance.patch
diff --git a/patches/server/0415-Potential-bed-API.patch b/patches/server/0420-Potential-bed-API.patch
index d63e2bb9ee..d63e2bb9ee 100644
--- a/patches/server/0415-Potential-bed-API.patch
+++ b/patches/server/0420-Potential-bed-API.patch
diff --git a/patches/server/0416-Wait-for-Async-Tasks-during-shutdown.patch b/patches/server/0421-Wait-for-Async-Tasks-during-shutdown.patch
index f30ef49645..6d308392ef 100644
--- a/patches/server/0416-Wait-for-Async-Tasks-during-shutdown.patch
+++ b/patches/server/0421-Wait-for-Async-Tasks-during-shutdown.patch
@@ -10,7 +10,7 @@ Adds a 5 second grace period for any async tasks to finish and warns
if any are still running after that delay just as reload does.
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
-index b1f8374253d04d1468f5d57792b30f91a274b97f..b6a05542a42b1f44b3a43fbcd333003e864e44ea 100644
+index ff94b07246b5e17be53f4e7294557c6744c62248..9c2589c7e0517f771b9ca06760273a0aecefb27d 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -911,6 +911,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -22,7 +22,7 @@ index b1f8374253d04d1468f5d57792b30f91a274b97f..b6a05542a42b1f44b3a43fbcd333003e
// CraftBukkit end
if (this.getConnection() != null) {
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-index 5ac4ff48b631649eac804553faf67330e9827806..fc7db6036a2c1b8f5b33a30e9604173dba63025b 100644
+index 6e4d06e0eadf3b97a3fa2b8b8499ce30335a4fff..f0f2a5e94e0a4b143befa422fa99e68316f93d7f 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -1011,6 +1011,35 @@ public final class CraftServer implements Server {
diff --git a/patches/server/0417-Ensure-EntityRaider-respects-game-and-entity-rules-f.patch b/patches/server/0422-Ensure-EntityRaider-respects-game-and-entity-rules-f.patch
index 94dbb79f58..94dbb79f58 100644
--- a/patches/server/0417-Ensure-EntityRaider-respects-game-and-entity-rules-f.patch
+++ b/patches/server/0422-Ensure-EntityRaider-respects-game-and-entity-rules-f.patch
diff --git a/patches/server/0418-Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch b/patches/server/0423-Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch
index f775181ba8..f775181ba8 100644
--- a/patches/server/0418-Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch
+++ b/patches/server/0423-Protect-Bedrock-and-End-Portal-Frames-from-being-des.patch
diff --git a/patches/server/0419-Reduce-MutableInt-allocations-from-light-engine.patch b/patches/server/0424-Reduce-MutableInt-allocations-from-light-engine.patch
index 3adb42bf18..3adb42bf18 100644
--- a/patches/server/0419-Reduce-MutableInt-allocations-from-light-engine.patch
+++ b/patches/server/0424-Reduce-MutableInt-allocations-from-light-engine.patch
diff --git a/patches/server/0420-Reduce-allocation-of-Vec3D-by-entity-tracker.patch b/patches/server/0425-Reduce-allocation-of-Vec3D-by-entity-tracker.patch
index f15e955db3..2b5c27897e 100644
--- a/patches/server/0420-Reduce-allocation-of-Vec3D-by-entity-tracker.patch
+++ b/patches/server/0425-Reduce-allocation-of-Vec3D-by-entity-tracker.patch
@@ -18,10 +18,10 @@ index 3167f5c6be39757e3cc42cbb17ab0cf13a2fe470..3768a71491ef7836b9739bdaec7a077c
private static long encode(double value) {
return Mth.lfloor(value * 4096.0D);
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
-index 5187988a22b55ac783147afe455a139662b67f7d..9077af957d284e341ca8327cb837dc9b4bb3ffee 100644
+index ea224e68b680c5e9ab38998f7709a4dbe3471b86..82eceddc15dcdf592dc5bbe6f1249f537be0a91e 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
-@@ -1931,9 +1931,13 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -2040,9 +2040,13 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
public void updatePlayer(ServerPlayer player) {
org.spigotmc.AsyncCatcher.catchOp("player tracker update"); // Spigot
if (player != this.entity) {
diff --git a/patches/server/0421-Ensure-safe-gateway-teleport.patch b/patches/server/0426-Ensure-safe-gateway-teleport.patch
index 6d352f74a8..6d352f74a8 100644
--- a/patches/server/0421-Ensure-safe-gateway-teleport.patch
+++ b/patches/server/0426-Ensure-safe-gateway-teleport.patch
diff --git a/patches/server/0422-Add-option-for-console-having-all-permissions.patch b/patches/server/0427-Add-option-for-console-having-all-permissions.patch
index d1e3317d94..d1e3317d94 100644
--- a/patches/server/0422-Add-option-for-console-having-all-permissions.patch
+++ b/patches/server/0427-Add-option-for-console-having-all-permissions.patch
diff --git a/patches/server/0423-Optimize-anyPlayerCloseEnoughForSpawning-to-use-dist.patch b/patches/server/0428-Optimize-anyPlayerCloseEnoughForSpawning-to-use-dist.patch
index 3f6b969086..3923c737df 100644
--- a/patches/server/0423-Optimize-anyPlayerCloseEnoughForSpawning-to-use-dist.patch
+++ b/patches/server/0428-Optimize-anyPlayerCloseEnoughForSpawning-to-use-dist.patch
@@ -6,46 +6,44 @@ Subject: [PATCH] Optimize anyPlayerCloseEnoughForSpawning to use distance maps
Use a distance map to find the players in range quickly
diff --git a/src/main/java/net/minecraft/server/level/ChunkHolder.java b/src/main/java/net/minecraft/server/level/ChunkHolder.java
-index 6e7d09cd48048957a14835b857ac708aafe8f664..4e8a79f2d3b6f52c6284bc9b0ce2423dc43a154f 100644
+index a52932d665ca45a5e066d7cef0ec0313d1c3f69f..0f75a109c06eb3113be74cf49ec560f5e2ea9cfc 100644
--- a/src/main/java/net/minecraft/server/level/ChunkHolder.java
+++ b/src/main/java/net/minecraft/server/level/ChunkHolder.java
-@@ -76,6 +76,23 @@ public class ChunkHolder {
- boolean isUpdateQueued = false; // Paper
- private final ChunkMap chunkMap; // Paper
+@@ -79,14 +79,27 @@ public class ChunkHolder {
-+ // Paper start - optimise anyPlayerCloseEnoughForSpawning
-+ // cached here to avoid a map lookup
-+ com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> playersInMobSpawnRange;
-+ com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> playersInChunkTickRange;
-+
-+ void onChunkAdd() {
+ // Paper start
+ public void onChunkAdd() {
+-
++ // Paper start - optimise anyPlayerCloseEnoughForSpawning
+ long key = net.minecraft.server.MCUtil.getCoordinateKey(this.pos);
+ this.playersInMobSpawnRange = this.chunkMap.playerMobSpawnMap.getObjectsInRange(key);
+ this.playersInChunkTickRange = this.chunkMap.playerChunkTickRangeMap.getObjectsInRange(key);
-+ }
-+
-+ void onChunkRemove() {
++ // Paper end - optimise anyPlayerCloseEnoughForSpawning
+ }
+
+ public void onChunkRemove() {
+-
++ // Paper start - optimise anyPlayerCloseEnoughForSpawning
+ this.playersInMobSpawnRange = null;
+ this.playersInChunkTickRange = null;
-+ }
++ // Paper end - optimise anyPlayerCloseEnoughForSpawning
+ }
+ // Paper end
+
++ // Paper start - optimise anyPlayerCloseEnoughForSpawning
++ // cached here to avoid a map lookup
++ com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> playersInMobSpawnRange;
++ com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> playersInChunkTickRange;
+ // Paper end - optimise anyPlayerCloseEnoughForSpawning
+
public ChunkHolder(ChunkPos pos, int level, LevelHeightAccessor world, LevelLightEngine lightingProvider, ChunkHolder.LevelChangeListener levelUpdateListener, ChunkHolder.PlayerProvider playersWatchingChunkProvider) {
this.futures = new AtomicReferenceArray(ChunkHolder.CHUNK_STATUSES.size());
this.fullChunkFuture = ChunkHolder.UNLOADED_LEVEL_CHUNK_FUTURE;
-@@ -97,6 +114,7 @@ public class ChunkHolder {
- this.setTicketLevel(level);
- this.changedBlocksPerSection = new ShortSet[world.getSectionsCount()];
- this.chunkMap = (ChunkMap)playersWatchingChunkProvider; // Paper
-+ this.onChunkAdd(); // Paper - optimise anyPlayerCloseEnoughForSpawning
- }
-
- // Paper start
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
-index 9077af957d284e341ca8327cb837dc9b4bb3ffee..6e27a89af794d411cce3c1c932c1f4910cec889c 100644
+index 82eceddc15dcdf592dc5bbe6f1249f537be0a91e..43ad735f57ab513311d700b42d7d0f2f1e43d0e7 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
-@@ -182,11 +182,23 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -196,11 +196,23 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
final CallbackExecutor chunkLoadConversionCallbackExecutor = new CallbackExecutor(); // Paper
// Paper start - distance maps
private final com.destroystokyo.paper.util.misc.PooledLinkedHashSets<ServerPlayer> pooledLinkedPlayerHashSets = new com.destroystokyo.paper.util.misc.PooledLinkedHashSets<>();
@@ -69,7 +67,7 @@ index 9077af957d284e341ca8327cb837dc9b4bb3ffee..6e27a89af794d411cce3c1c932c1f491
// Paper start - per player mob spawning
if (this.playerMobDistanceMap != null) {
this.playerMobDistanceMap.add(player, chunkX, chunkZ, this.distanceManager.getSimulationDistance());
-@@ -196,6 +208,10 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -210,6 +222,10 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
void removePlayerFromDistanceMaps(ServerPlayer player) {
@@ -80,7 +78,7 @@ index 9077af957d284e341ca8327cb837dc9b4bb3ffee..6e27a89af794d411cce3c1c932c1f491
// Paper start - per player mob spawning
if (this.playerMobDistanceMap != null) {
this.playerMobDistanceMap.remove(player);
-@@ -207,6 +223,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -221,6 +237,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
int chunkX = MCUtil.getChunkCoordinate(player.getX());
int chunkZ = MCUtil.getChunkCoordinate(player.getZ());
// Note: players need to be explicitly added to distance maps before they can be updated
@@ -88,7 +86,7 @@ index 9077af957d284e341ca8327cb837dc9b4bb3ffee..6e27a89af794d411cce3c1c932c1f491
// Paper start - per player mob spawning
if (this.playerMobDistanceMap != null) {
this.playerMobDistanceMap.update(player, chunkX, chunkZ, this.distanceManager.getSimulationDistance());
-@@ -300,6 +317,38 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -323,6 +340,38 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
this.regionManagers.add(this.dataRegionManager);
// Paper end
this.playerMobDistanceMap = this.level.paperConfig().entities.spawning.perPlayerMobSpawns ? new com.destroystokyo.paper.util.misc.PlayerAreaMap(this.pooledLinkedPlayerHashSets) : null; // Paper
@@ -127,23 +125,7 @@ index 9077af957d284e341ca8327cb837dc9b4bb3ffee..6e27a89af794d411cce3c1c932c1f491
}
protected ChunkGenerator generator() {
-@@ -555,6 +604,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
- holder = (ChunkHolder) this.pendingUnloads.remove(pos);
- if (holder != null) {
- holder.setTicketLevel(level);
-+ holder.onChunkAdd(); // Paper - optimise anyPlayerCloseEnoughForSpawning - PUT HERE AFTER RE-ADDING ONLY
- } else {
- holder = new ChunkHolder(new ChunkPos(pos), level, this.level, this.lightEngine, this.queueSorter, this);
- // Paper start
-@@ -650,6 +700,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
- ChunkHolder playerchunk = (ChunkHolder) this.updatingChunkMap.remove(j);
-
- if (playerchunk != null) {
-+ playerchunk.onChunkRemove(); // Paper
- this.pendingUnloads.put(j, playerchunk);
- this.modified = true;
- ++i;
-@@ -1415,43 +1466,48 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -1524,43 +1573,48 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
return this.anyPlayerCloseEnoughForSpawning(pos, false);
}
@@ -224,7 +206,7 @@ index 9077af957d284e341ca8327cb837dc9b4bb3ffee..6e27a89af794d411cce3c1c932c1f491
public List<ServerPlayer> getPlayersCloseForSpawning(ChunkPos pos) {
diff --git a/src/main/java/net/minecraft/server/level/DistanceManager.java b/src/main/java/net/minecraft/server/level/DistanceManager.java
-index 4a9d0fca55b71f817defcb4286154c0a47bede03..62118348d6fb00f063507debb488e1ff431d139c 100644
+index f456ba4bf699e1f6bd15726a037a0047b6ca7380..b2df5e18ce5260a9781052db7afb0b9786fb887c 100644
--- a/src/main/java/net/minecraft/server/level/DistanceManager.java
+++ b/src/main/java/net/minecraft/server/level/DistanceManager.java
@@ -49,7 +49,7 @@ public abstract class DistanceManager {
@@ -236,16 +218,16 @@ index 4a9d0fca55b71f817defcb4286154c0a47bede03..62118348d6fb00f063507debb488e1ff
private final TickingTracker tickingTicketsTracker = new TickingTracker();
private final DistanceManager.PlayerTicketTracker playerTicketManager = new DistanceManager.PlayerTicketTracker(33);
// Paper start use a queue, but still keep unique requirement
-@@ -140,7 +140,7 @@ public abstract class DistanceManager {
+@@ -141,7 +141,7 @@ public abstract class DistanceManager {
protected abstract ChunkHolder updateChunkScheduling(long pos, int level, @Nullable ChunkHolder holder, int k);
public boolean runAllUpdates(ChunkMap chunkStorage) {
- this.naturalSpawnChunkCounter.runAllUpdates();
+ //this.f.a(); // Paper - no longer used
this.tickingTicketsTracker.runAllUpdates();
+ org.spigotmc.AsyncCatcher.catchOp("DistanceManagerTick"); // Paper
this.playerTicketManager.runAllUpdates();
- int i = Integer.MAX_VALUE - this.ticketTracker.runDistanceUpdates(Integer.MAX_VALUE);
-@@ -289,7 +289,7 @@ public abstract class DistanceManager {
+@@ -429,7 +429,7 @@ public abstract class DistanceManager {
((ObjectSet) this.playersPerChunk.computeIfAbsent(i, (j) -> {
return new ObjectOpenHashSet();
})).add(player);
@@ -254,7 +236,7 @@ index 4a9d0fca55b71f817defcb4286154c0a47bede03..62118348d6fb00f063507debb488e1ff
this.playerTicketManager.update(i, 0, true);
this.tickingTicketsTracker.addTicket(TicketType.PLAYER, chunkcoordintpair, this.getPlayerTicketLevel(), chunkcoordintpair);
}
-@@ -303,7 +303,7 @@ public abstract class DistanceManager {
+@@ -443,7 +443,7 @@ public abstract class DistanceManager {
if (objectset != null) objectset.remove(player); // Paper - some state corruption happens here, don't crash, clean up gracefully.
if (objectset == null || objectset.isEmpty()) { // Paper
this.playersPerChunk.remove(i);
@@ -263,7 +245,7 @@ index 4a9d0fca55b71f817defcb4286154c0a47bede03..62118348d6fb00f063507debb488e1ff
this.playerTicketManager.update(i, Integer.MAX_VALUE, false);
this.tickingTicketsTracker.removeTicket(TicketType.PLAYER, chunkcoordintpair, this.getPlayerTicketLevel(), chunkcoordintpair);
}
-@@ -347,13 +347,17 @@ public abstract class DistanceManager {
+@@ -487,13 +487,17 @@ public abstract class DistanceManager {
// Paper end
public int getNaturalSpawnChunkCount() {
@@ -286,10 +268,10 @@ index 4a9d0fca55b71f817defcb4286154c0a47bede03..62118348d6fb00f063507debb488e1ff
public String getDebugStatus() {
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
-index 42b4214a1319691e9a6cb0c5fafaeeff821f3f99..1d9a0f6effa1654609f4d0752ec69eed6ab7134b 100644
+index a986051dead41f1a9f70e5e00572255e9939c4a9..70c5e151d47217d417b91105ac63f17a2eb957bf 100644
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
-@@ -873,6 +873,37 @@ public class ServerChunkCache extends ChunkSource {
+@@ -727,6 +727,37 @@ public class ServerChunkCache extends ChunkSource {
if (flag) {
this.chunkMap.tick();
} else {
@@ -327,7 +309,7 @@ index 42b4214a1319691e9a6cb0c5fafaeeff821f3f99..1d9a0f6effa1654609f4d0752ec69eed
LevelData worlddata = this.level.getLevelData();
ProfilerFiller gameprofilerfiller = this.level.getProfiler();
-@@ -916,15 +947,7 @@ public class ServerChunkCache extends ChunkSource {
+@@ -770,15 +801,7 @@ public class ServerChunkCache extends ChunkSource {
boolean flag2 = this.level.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && !this.level.players().isEmpty(); // CraftBukkit
Collections.shuffle(list);
@@ -344,7 +326,7 @@ index 42b4214a1319691e9a6cb0c5fafaeeff821f3f99..1d9a0f6effa1654609f4d0752ec69eed
Iterator iterator1 = list.iterator();
while (iterator1.hasNext()) {
-@@ -932,9 +955,9 @@ public class ServerChunkCache extends ChunkSource {
+@@ -786,9 +809,9 @@ public class ServerChunkCache extends ChunkSource {
LevelChunk chunk1 = chunkproviderserver_a.chunk;
ChunkPos chunkcoordintpair = chunk1.getPos();
@@ -357,10 +339,10 @@ index 42b4214a1319691e9a6cb0c5fafaeeff821f3f99..1d9a0f6effa1654609f4d0752ec69eed
}
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-index acc64abd9420b81ed4c8c17cf6a9f5bc5d35f116..06e711aa9a0afedda48395ba2ee369bb211584da 100644
+index 971f72c1dd713077c128279a78ed37f15aedeff6..29a03760f092a004a47e75120841d80e696b6c3d 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-@@ -262,6 +262,7 @@ public class ServerPlayer extends Player {
+@@ -263,6 +263,7 @@ public class ServerPlayer extends Player {
// CraftBukkit end
public PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper
diff --git a/patches/server/0424-Use-distance-map-to-optimise-entity-tracker.patch b/patches/server/0429-Use-distance-map-to-optimise-entity-tracker.patch
index a1f1dae611..6b7c2e2afd 100644
--- a/patches/server/0424-Use-distance-map-to-optimise-entity-tracker.patch
+++ b/patches/server/0429-Use-distance-map-to-optimise-entity-tracker.patch
@@ -6,7 +6,7 @@ Subject: [PATCH] Use distance map to optimise entity tracker
Use the distance map to find candidate players for tracking.
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
-index 6e27a89af794d411cce3c1c932c1f4910cec889c..6188f35e2b5300b6ff4a16e4d6e0e4a846261f8a 100644
+index 43ad735f57ab513311d700b42d7d0f2f1e43d0e7..b0e0f85e04438affb8d8e0f75055ea83d0c03bcd 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -66,6 +66,7 @@ import net.minecraft.network.protocol.game.ClientboundSetEntityLinkPacket;
@@ -17,7 +17,7 @@ index 6e27a89af794d411cce3c1c932c1f4910cec889c..6188f35e2b5300b6ff4a16e4d6e0e4a8
import net.minecraft.server.level.progress.ChunkProgressListener;
import net.minecraft.server.network.ServerPlayerConnection;
import net.minecraft.util.CsvOutput;
-@@ -193,10 +194,35 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -207,10 +208,35 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
public final com.destroystokyo.paper.util.misc.PlayerAreaMap playerMobSpawnMap; // this map is absent from updateMaps since it's controlled at the start of the chunkproviderserver tick
public final com.destroystokyo.paper.util.misc.PlayerAreaMap playerChunkTickRangeMap;
// Paper end - optimise ChunkMap#anyPlayerCloseEnoughForSpawning
@@ -53,7 +53,7 @@ index 6e27a89af794d411cce3c1c932c1f4910cec889c..6188f35e2b5300b6ff4a16e4d6e0e4a8
// Note: players need to be explicitly added to distance maps before they can be updated
this.playerChunkTickRangeMap.add(player, chunkX, chunkZ, DistanceManager.MOB_SPAWN_RANGE); // Paper - optimise ChunkMap#anyPlayerCloseEnoughForSpawning
// Paper start - per player mob spawning
-@@ -208,6 +234,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -222,6 +248,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
void removePlayerFromDistanceMaps(ServerPlayer player) {
@@ -65,7 +65,7 @@ index 6e27a89af794d411cce3c1c932c1f4910cec889c..6188f35e2b5300b6ff4a16e4d6e0e4a8
// Paper start - optimise ChunkMap#anyPlayerCloseEnoughForSpawning
this.playerMobSpawnMap.remove(player);
this.playerChunkTickRangeMap.remove(player);
-@@ -223,6 +254,14 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -237,6 +268,14 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
int chunkX = MCUtil.getChunkCoordinate(player.getX());
int chunkZ = MCUtil.getChunkCoordinate(player.getZ());
// Note: players need to be explicitly added to distance maps before they can be updated
@@ -80,7 +80,7 @@ index 6e27a89af794d411cce3c1c932c1f4910cec889c..6188f35e2b5300b6ff4a16e4d6e0e4a8
this.playerChunkTickRangeMap.update(player, chunkX, chunkZ, DistanceManager.MOB_SPAWN_RANGE); // Paper - optimise ChunkMap#anyPlayerCloseEnoughForSpawning
// Paper start - per player mob spawning
if (this.playerMobDistanceMap != null) {
-@@ -317,6 +356,45 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -340,6 +379,45 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
this.regionManagers.add(this.dataRegionManager);
// Paper end
this.playerMobDistanceMap = this.level.paperConfig().entities.spawning.perPlayerMobSpawns ? new com.destroystokyo.paper.util.misc.PlayerAreaMap(this.pooledLinkedPlayerHashSets) : null; // Paper
@@ -126,7 +126,7 @@ index 6e27a89af794d411cce3c1c932c1f4910cec889c..6188f35e2b5300b6ff4a16e4d6e0e4a8
// Paper start - optimise ChunkMap#anyPlayerCloseEnoughForSpawning
this.playerChunkTickRangeMap = new com.destroystokyo.paper.util.misc.PlayerAreaMap(this.pooledLinkedPlayerHashSets,
(ServerPlayer player, int rangeX, int rangeZ, int currPosX, int currPosZ, int prevPosX, int prevPosZ,
-@@ -1589,17 +1667,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -1696,17 +1774,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
}
public void move(ServerPlayer player) {
@@ -145,7 +145,7 @@ index 6e27a89af794d411cce3c1c932c1f4910cec889c..6188f35e2b5300b6ff4a16e4d6e0e4a8
int i = SectionPos.blockToSectionCoord(player.getBlockX());
int j = SectionPos.blockToSectionCoord(player.getBlockZ());
-@@ -1726,7 +1794,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -1833,7 +1901,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
entity.tracker = playerchunkmap_entitytracker; // Paper - Fast access to tracker
this.entityMap.put(entity.getId(), playerchunkmap_entitytracker);
@@ -154,7 +154,7 @@ index 6e27a89af794d411cce3c1c932c1f4910cec889c..6188f35e2b5300b6ff4a16e4d6e0e4a8
if (entity instanceof ServerPlayer) {
ServerPlayer entityplayer = (ServerPlayer) entity;
-@@ -1770,7 +1838,37 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -1877,7 +1945,37 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
entity.tracker = null; // Paper - We're no longer tracked
}
@@ -192,7 +192,7 @@ index 6e27a89af794d411cce3c1c932c1f4910cec889c..6188f35e2b5300b6ff4a16e4d6e0e4a8
List<ServerPlayer> list = Lists.newArrayList();
List<ServerPlayer> list1 = this.level.players();
ObjectIterator objectiterator = this.entityMap.values().iterator();
-@@ -1846,23 +1944,31 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -1953,23 +2051,31 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
DebugPackets.sendPoiPacketsForChunk(this.level, chunk.getPos());
List<Entity> list = Lists.newArrayList();
List<Entity> list1 = Lists.newArrayList();
@@ -236,7 +236,7 @@ index 6e27a89af794d411cce3c1c932c1f4910cec889c..6188f35e2b5300b6ff4a16e4d6e0e4a8
Iterator iterator;
Entity entity1;
-@@ -1938,6 +2044,42 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -2045,6 +2151,42 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
this.lastSectionPos = SectionPos.of((EntityAccess) entity);
}
@@ -280,7 +280,7 @@ index 6e27a89af794d411cce3c1c932c1f4910cec889c..6188f35e2b5300b6ff4a16e4d6e0e4a8
return object instanceof ChunkMap.TrackedEntity ? ((ChunkMap.TrackedEntity) object).entity.getId() == this.entity.getId() : false;
}
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
-index 70978ba28cec4dd3e64bf380c0669b3bcf4a640b..0f85956d4d1c98225ff7cff7abad217a124f0dfc 100644
+index 74e13ae8b1e6a9365d46f5684ee58e42658d2341..0a0fb24cd12d77e0c29eb6e0a20eacfc04330bf3 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -57,6 +57,7 @@ import net.minecraft.network.syncher.EntityDataSerializers;
diff --git a/patches/server/0425-Optimize-ServerLevels-chunk-level-checking-methods.patch b/patches/server/0430-Optimize-ServerLevels-chunk-level-checking-methods.patch
index 5e016b22d6..2bcf0781f9 100644
--- a/patches/server/0425-Optimize-ServerLevels-chunk-level-checking-methods.patch
+++ b/patches/server/0430-Optimize-ServerLevels-chunk-level-checking-methods.patch
@@ -8,10 +8,10 @@ so inline where possible, and avoid the abstraction of the
Either class.
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index a7db54a94a5017e737ce9682a52eed7405af8cc1..22a0ca38ae03b8064db7f77dd17335ed4abc72bc 100644
+index a778b4b5b2413c25c2f0f0efc72ba1d362d89acf..c9ecc7593c299b351308634db44596a76fd0c09b 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
-@@ -2253,19 +2253,22 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -2255,19 +2255,22 @@ public class ServerLevel extends Level implements WorldGenLevel {
}
private boolean isPositionTickingWithEntitiesLoaded(long chunkPos) {
@@ -52,10 +52,10 @@ index 2d41f619577b41d6420159668bbab70fb6c762eb..ed0b136e99def41d4377f2004477826b
public static int getX(long pos) {
diff --git a/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java b/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java
-index 6e3d02fb68741fc3cf7d74ec659a37e5a1ecac5c..e53e912351a0753c429512f018281a656837bde2 100644
+index 16519a6414f6f6418de40b714555a52631980617..a5dc8e715c86c1e70a9cf3d99c9cd457a6666b70 100644
--- a/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java
+++ b/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java
-@@ -383,6 +383,11 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
+@@ -395,6 +395,11 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
public LevelEntityGetter<T> getEntityGetter() {
return this.entityGetter;
}
diff --git a/patches/server/0427-Fix-villager-trading-demand-MC-163962.patch b/patches/server/0431-Fix-villager-trading-demand-MC-163962.patch
index fb5e330854..fb5e330854 100644
--- a/patches/server/0427-Fix-villager-trading-demand-MC-163962.patch
+++ b/patches/server/0431-Fix-villager-trading-demand-MC-163962.patch
diff --git a/patches/server/0428-Maps-shouldn-t-load-chunks.patch b/patches/server/0432-Maps-shouldn-t-load-chunks.patch
index 3ab19f357a..3ab19f357a 100644
--- a/patches/server/0428-Maps-shouldn-t-load-chunks.patch
+++ b/patches/server/0432-Maps-shouldn-t-load-chunks.patch
diff --git a/patches/server/0429-Use-seed-based-lookup-for-Treasure-Maps-Fixes-lag-fr.patch b/patches/server/0433-Use-seed-based-lookup-for-Treasure-Maps-Fixes-lag-fr.patch
index 9ed5e37d35..9ed5e37d35 100644
--- a/patches/server/0429-Use-seed-based-lookup-for-Treasure-Maps-Fixes-lag-fr.patch
+++ b/patches/server/0433-Use-seed-based-lookup-for-Treasure-Maps-Fixes-lag-fr.patch
diff --git a/patches/server/0430-Fix-CraftScheduler-runTaskTimerAsynchronously-Plugin.patch b/patches/server/0434-Fix-CraftScheduler-runTaskTimerAsynchronously-Plugin.patch
index 1cafad18f3..1cafad18f3 100644
--- a/patches/server/0430-Fix-CraftScheduler-runTaskTimerAsynchronously-Plugin.patch
+++ b/patches/server/0434-Fix-CraftScheduler-runTaskTimerAsynchronously-Plugin.patch
diff --git a/patches/server/0431-Fix-piston-physics-inconsistency-MC-188840.patch b/patches/server/0435-Fix-piston-physics-inconsistency-MC-188840.patch
index dcc303244a..dcc303244a 100644
--- a/patches/server/0431-Fix-piston-physics-inconsistency-MC-188840.patch
+++ b/patches/server/0435-Fix-piston-physics-inconsistency-MC-188840.patch
diff --git a/patches/server/0432-Fix-sand-duping.patch b/patches/server/0436-Fix-sand-duping.patch
index 5780d77de8..5780d77de8 100644
--- a/patches/server/0432-Fix-sand-duping.patch
+++ b/patches/server/0436-Fix-sand-duping.patch
diff --git a/patches/server/0433-Fix-missing-chunks-due-to-integer-overflow.patch b/patches/server/0437-Fix-missing-chunks-due-to-integer-overflow.patch
index 94b8d07c3a..94b8d07c3a 100644
--- a/patches/server/0433-Fix-missing-chunks-due-to-integer-overflow.patch
+++ b/patches/server/0437-Fix-missing-chunks-due-to-integer-overflow.patch
diff --git a/patches/server/0434-Prevent-position-desync-in-playerconnection-causing-.patch b/patches/server/0438-Prevent-position-desync-in-playerconnection-causing-.patch
index 8abc2018d3..8abc2018d3 100644
--- a/patches/server/0434-Prevent-position-desync-in-playerconnection-causing-.patch
+++ b/patches/server/0438-Prevent-position-desync-in-playerconnection-causing-.patch
diff --git a/patches/server/0435-Inventory-getHolder-method-without-block-snapshot.patch b/patches/server/0439-Inventory-getHolder-method-without-block-snapshot.patch
index 9ed9fe0826..9ed9fe0826 100644
--- a/patches/server/0435-Inventory-getHolder-method-without-block-snapshot.patch
+++ b/patches/server/0439-Inventory-getHolder-method-without-block-snapshot.patch
diff --git a/patches/server/0436-Improve-Arrow-API.patch b/patches/server/0440-Improve-Arrow-API.patch
index 47bb897a5a..47bb897a5a 100644
--- a/patches/server/0436-Improve-Arrow-API.patch
+++ b/patches/server/0440-Improve-Arrow-API.patch
diff --git a/patches/server/0437-Add-and-implement-PlayerRecipeBookClickEvent.patch b/patches/server/0441-Add-and-implement-PlayerRecipeBookClickEvent.patch
index c3f21e2698..c3f21e2698 100644
--- a/patches/server/0437-Add-and-implement-PlayerRecipeBookClickEvent.patch
+++ b/patches/server/0441-Add-and-implement-PlayerRecipeBookClickEvent.patch
diff --git a/patches/server/0438-Hide-sync-chunk-writes-behind-flag.patch b/patches/server/0442-Hide-sync-chunk-writes-behind-flag.patch
index 1d9e0f2b56..1d9e0f2b56 100644
--- a/patches/server/0438-Hide-sync-chunk-writes-behind-flag.patch
+++ b/patches/server/0442-Hide-sync-chunk-writes-behind-flag.patch
diff --git a/patches/server/0439-Add-permission-for-command-blocks.patch b/patches/server/0443-Add-permission-for-command-blocks.patch
index 4acfd8ed30..4acfd8ed30 100644
--- a/patches/server/0439-Add-permission-for-command-blocks.patch
+++ b/patches/server/0443-Add-permission-for-command-blocks.patch
diff --git a/patches/server/0440-Ensure-Entity-AABB-s-are-never-invalid.patch b/patches/server/0444-Ensure-Entity-AABB-s-are-never-invalid.patch
index b5cd289e5a..756a326a3a 100644
--- a/patches/server/0440-Ensure-Entity-AABB-s-are-never-invalid.patch
+++ b/patches/server/0444-Ensure-Entity-AABB-s-are-never-invalid.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] Ensure Entity AABB's are never invalid
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
-index 0f85956d4d1c98225ff7cff7abad217a124f0dfc..258aa2ee24742d48be08940f147e1d998e667fb8 100644
+index 0a0fb24cd12d77e0c29eb6e0a20eacfc04330bf3..7e36e53d44b5efbd6498caecb717bec1dcbec96d 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -662,8 +662,8 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
diff --git a/patches/server/0441-Fix-Per-World-Difficulty-Remembering-Difficulty.patch b/patches/server/0445-Fix-Per-World-Difficulty-Remembering-Difficulty.patch
index 0bf7d5bc7e..0f8476767c 100644
--- a/patches/server/0441-Fix-Per-World-Difficulty-Remembering-Difficulty.patch
+++ b/patches/server/0445-Fix-Per-World-Difficulty-Remembering-Difficulty.patch
@@ -76,10 +76,10 @@ index e42df2956e2d852a5a4c8fdeda395a3efd32c44c..da83f111199a6b4c712a9bb8ab6f1d1b
@Override
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-index 06e711aa9a0afedda48395ba2ee369bb211584da..28944fc50ea43a3ea40bd1e69c560c8fe022337e 100644
+index 29a03760f092a004a47e75120841d80e696b6c3d..be7d2275548936beade4aba02dc5b14fec95117a 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-@@ -1128,7 +1128,7 @@ public class ServerPlayer extends Player {
+@@ -1144,7 +1144,7 @@ public class ServerPlayer extends Player {
this.isChangingDimension = true; // CraftBukkit - Set teleport invulnerability only if player changing worlds
this.connection.send(new ClientboundRespawnPacket(worldserver.dimensionTypeId(), worldserver.dimension(), BiomeManager.obfuscateSeed(worldserver.getSeed()), this.gameMode.getGameModeForPlayer(), this.gameMode.getPreviousGameModeForPlayer(), worldserver.isDebug(), worldserver.isFlat(), true, this.getLastDeathLocation()));
diff --git a/patches/server/0442-Paper-dumpitem-command.patch b/patches/server/0446-Paper-dumpitem-command.patch
index 930a212a00..930a212a00 100644
--- a/patches/server/0442-Paper-dumpitem-command.patch
+++ b/patches/server/0446-Paper-dumpitem-command.patch
diff --git a/patches/server/0443-Don-t-allow-null-UUID-s-for-chat.patch b/patches/server/0447-Don-t-allow-null-UUID-s-for-chat.patch
index 9c92814826..9c92814826 100644
--- a/patches/server/0443-Don-t-allow-null-UUID-s-for-chat.patch
+++ b/patches/server/0447-Don-t-allow-null-UUID-s-for-chat.patch
diff --git a/patches/server/0444-Improve-Legacy-Component-serialization-size.patch b/patches/server/0448-Improve-Legacy-Component-serialization-size.patch
index 866302739f..866302739f 100644
--- a/patches/server/0444-Improve-Legacy-Component-serialization-size.patch
+++ b/patches/server/0448-Improve-Legacy-Component-serialization-size.patch
diff --git a/patches/server/0445-Optimize-Bit-Operations-by-inlining.patch b/patches/server/0449-Optimize-Bit-Operations-by-inlining.patch
index c1cce4278a..c1cce4278a 100644
--- a/patches/server/0445-Optimize-Bit-Operations-by-inlining.patch
+++ b/patches/server/0449-Optimize-Bit-Operations-by-inlining.patch
diff --git a/patches/server/0446-Add-Plugin-Tickets-to-API-Chunk-Methods.patch b/patches/server/0450-Add-Plugin-Tickets-to-API-Chunk-Methods.patch
index 31dc8e2524..506018715e 100644
--- a/patches/server/0446-Add-Plugin-Tickets-to-API-Chunk-Methods.patch
+++ b/patches/server/0450-Add-Plugin-Tickets-to-API-Chunk-Methods.patch
@@ -22,7 +22,7 @@ wants it to collect even faster, they can restore that setting back to 1 instead
Not adding it to .getType() though to keep behavior consistent with vanilla for performance reasons.
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-index 979d0116e72417eec26193cd1e106dc9d27cdbe0..c7a6143ebb2ed0a0977e1d38c8adcccf09800638 100644
+index 99a9bf12f2e3e6ac5457da53f6f12118efce5d82..58f361ad664ba45c496ab0817c7ab5e1a017b807 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -360,7 +360,7 @@ public final class CraftServer implements Server {
@@ -44,10 +44,10 @@ index 979d0116e72417eec26193cd1e106dc9d27cdbe0..c7a6143ebb2ed0a0977e1d38c8adcccf
this.printSaveWarning = false;
console.autosavePeriod = this.configuration.getInt("ticks-per.autosave");
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-index 21927118d1762302dc560b385fd3a4322840031f..b234ba968e82ddf1e8f7c84d3a17659e3beda2b3 100644
+index a8ab324bfbaaf946af5998402588244465dd7286..710270775cd47e8df1146ad0636648568d45ac75 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-@@ -283,8 +283,21 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+@@ -282,8 +282,21 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@Override
public Chunk getChunkAt(int x, int z) {
@@ -70,7 +70,7 @@ index 21927118d1762302dc560b385fd3a4322840031f..b234ba968e82ddf1e8f7c84d3a17659e
@Override
public Chunk getChunkAt(Block block) {
-@@ -351,7 +364,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+@@ -350,7 +363,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
public boolean unloadChunkRequest(int x, int z) {
org.spigotmc.AsyncCatcher.catchOp("chunk unload"); // Spigot
if (this.isChunkLoaded(x, z)) {
@@ -79,7 +79,7 @@ index 21927118d1762302dc560b385fd3a4322840031f..b234ba968e82ddf1e8f7c84d3a17659e
}
return true;
-@@ -434,9 +447,12 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+@@ -433,9 +446,12 @@ public class CraftWorld extends CraftRegionAccessor implements World {
org.spigotmc.AsyncCatcher.catchOp("chunk load"); // Spigot
// Paper start - Optimize this method
ChunkPos chunkPos = new ChunkPos(x, z);
@@ -93,7 +93,7 @@ index 21927118d1762302dc560b385fd3a4322840031f..b234ba968e82ddf1e8f7c84d3a17659e
if (immediate == null) {
immediate = world.getChunkSource().chunkMap.getUnloadingChunk(x, z);
}
-@@ -444,7 +460,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+@@ -443,7 +459,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
if (!(immediate instanceof ImposterProtoChunk) && !(immediate instanceof net.minecraft.world.level.chunk.LevelChunk)) {
return false; // not full status
}
@@ -102,7 +102,7 @@ index 21927118d1762302dc560b385fd3a4322840031f..b234ba968e82ddf1e8f7c84d3a17659e
world.getChunk(x, z); // make sure we're at ticket level 32 or lower
return true;
}
-@@ -470,7 +486,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+@@ -469,7 +485,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
// we do this so we do not re-read the chunk data on disk
}
@@ -111,11 +111,11 @@ index 21927118d1762302dc560b385fd3a4322840031f..b234ba968e82ddf1e8f7c84d3a17659e
world.getChunkSource().getChunk(x, z, ChunkStatus.FULL, true);
return true;
// Paper end
-@@ -2063,6 +2079,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
-
- return this.world.getChunkSource().getChunkAtAsynchronously(x, z, gen, urgent).thenComposeAsync((either) -> {
- net.minecraft.world.level.chunk.LevelChunk chunk = (net.minecraft.world.level.chunk.LevelChunk) either.left().orElse(null);
-+ if (chunk != null) addTicket(x, z); // Paper
- return java.util.concurrent.CompletableFuture.completedFuture(chunk == null ? null : chunk.getBukkitChunk());
- }, net.minecraft.server.MinecraftServer.getServer());
- }
+@@ -2150,6 +2166,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+ net.minecraft.server.ChunkSystem.scheduleChunkLoad(this.getHandle(), x, z, gen, ChunkStatus.FULL, true, priority, (c) -> {
+ net.minecraft.server.MinecraftServer.getServer().scheduleOnMain(() -> {
+ net.minecraft.world.level.chunk.LevelChunk chunk = (net.minecraft.world.level.chunk.LevelChunk)c;
++ if (chunk != null) addTicket(x, z); // Paper
+ ret.complete(chunk == null ? null : chunk.getBukkitChunk());
+ });
+ });
diff --git a/patches/server/0447-incremental-chunk-and-player-saving.patch b/patches/server/0451-incremental-chunk-and-player-saving.patch
index cb5d5e6826..e993eebc44 100644
--- a/patches/server/0447-incremental-chunk-and-player-saving.patch
+++ b/patches/server/0451-incremental-chunk-and-player-saving.patch
@@ -53,19 +53,19 @@ index 7d2fee97f4d08eae245475c4b60c1a7ba46c840d..48650bc1c09b18f1b57d9828dfe27f51
// Paper start - move executeAll() into full server tick timing
try (co.aikar.timings.Timing ignored = MinecraftTimings.processTasksTimer.startTiming()) {
diff --git a/src/main/java/net/minecraft/server/level/ChunkHolder.java b/src/main/java/net/minecraft/server/level/ChunkHolder.java
-index 4e8a79f2d3b6f52c6284bc9b0ce2423dc43a154f..36a9d52d9af3bc398010c52dc16ab23e53f2702a 100644
+index 0f75a109c06eb3113be74cf49ec560f5e2ea9cfc..ac42029596ae0c824bf33a4058ac1009740e29ea 100644
--- a/src/main/java/net/minecraft/server/level/ChunkHolder.java
+++ b/src/main/java/net/minecraft/server/level/ChunkHolder.java
-@@ -92,6 +92,8 @@ public class ChunkHolder {
- this.playersInChunkTickRange = null;
- }
+@@ -99,6 +99,8 @@ public class ChunkHolder {
+ com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> playersInMobSpawnRange;
+ com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> playersInChunkTickRange;
// Paper end - optimise anyPlayerCloseEnoughForSpawning
+ long lastAutoSaveTime; // Paper - incremental autosave
+ long inactiveTimeStart; // Paper - incremental autosave
public ChunkHolder(ChunkPos pos, int level, LevelHeightAccessor world, LevelLightEngine lightingProvider, ChunkHolder.LevelChangeListener levelUpdateListener, ChunkHolder.PlayerProvider playersWatchingChunkProvider) {
this.futures = new AtomicReferenceArray(ChunkHolder.CHUNK_STATUSES.size());
-@@ -502,7 +504,19 @@ public class ChunkHolder {
+@@ -527,7 +529,19 @@ public class ChunkHolder {
boolean flag2 = playerchunk_state.isOrAfter(ChunkHolder.FullChunkStatus.BORDER);
boolean flag3 = playerchunk_state1.isOrAfter(ChunkHolder.FullChunkStatus.BORDER);
@@ -85,7 +85,7 @@ index 4e8a79f2d3b6f52c6284bc9b0ce2423dc43a154f..36a9d52d9af3bc398010c52dc16ab23e
if (!flag2 && flag3) {
int expectCreateCount = ++this.fullChunkCreateCount; // Paper
this.fullChunkFuture = chunkStorage.prepareAccessibleChunk(this);
-@@ -633,9 +647,33 @@ public class ChunkHolder {
+@@ -689,8 +703,32 @@ public class ChunkHolder {
}
public void refreshAccessibility() {
@@ -107,20 +107,19 @@ index 4e8a79f2d3b6f52c6284bc9b0ce2423dc43a154f..36a9d52d9af3bc398010c52dc16ab23e
+ }
+ }
+ // Paper end
- }
-
++ }
++
+ // Paper start - incremental autosave
+ public boolean setHasBeenLoaded() {
+ this.wasAccessibleSinceLastSave = getFullChunkStatus(this.ticketLevel).isOrAfter(ChunkHolder.FullChunkStatus.BORDER);
+ return this.wasAccessibleSinceLastSave;
-+ }
+ }
+ // Paper end
-+
+
public void replaceProtoChunk(ImposterProtoChunk chunk) {
for (int i = 0; i < this.futures.length(); ++i) {
- CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> completablefuture = (CompletableFuture) this.futures.get(i);
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
-index 6188f35e2b5300b6ff4a16e4d6e0e4a846261f8a..4d74eb7883c72fb42275fc5358917244bb36181d 100644
+index b0e0f85e04438affb8d8e0f75055ea83d0c03bcd..7493da0f1c3f8ab0ebc517347ef23fbe2747a306 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -103,6 +103,7 @@ import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemp
@@ -131,7 +130,7 @@ index 6188f35e2b5300b6ff4a16e4d6e0e4a846261f8a..4d74eb7883c72fb42275fc5358917244
import org.apache.commons.lang3.mutable.MutableBoolean;
import org.apache.commons.lang3.mutable.MutableObject;
import org.slf4j.Logger;
-@@ -712,6 +713,64 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -779,6 +780,64 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
}
@@ -194,13 +193,13 @@ index 6188f35e2b5300b6ff4a16e4d6e0e4a846261f8a..4d74eb7883c72fb42275fc5358917244
+ // Paper end
+
protected void saveAllChunks(boolean flush) {
- if (flush) {
- List<ChunkHolder> list = (List) this.visibleChunkMap.values().stream().filter(ChunkHolder::wasAccessibleSinceLastSave).peek(ChunkHolder::refreshAccessibility).collect(Collectors.toList());
-@@ -796,13 +855,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+ // Paper start - do not overload I/O threads with too much work when saving
+ int[] saved = new int[1];
+@@ -874,13 +933,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
}
int l = 0;
-- ObjectIterator objectiterator = this.visibleChunkMap.values().iterator();
+- Iterator objectiterator = net.minecraft.server.ChunkSystem.getVisibleChunkHolders(this.level).iterator(); // Paper
-
- while (l < 20 && shouldKeepTicking.getAsBoolean() && objectiterator.hasNext()) {
- if (this.saveChunkIfNeeded((ChunkHolder) objectiterator.next())) {
@@ -211,7 +210,7 @@ index 6188f35e2b5300b6ff4a16e4d6e0e4a846261f8a..4d74eb7883c72fb42275fc5358917244
}
-@@ -840,6 +893,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -916,6 +969,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
this.level.unload(chunk);
}
@@ -219,7 +218,7 @@ index 6188f35e2b5300b6ff4a16e4d6e0e4a846261f8a..4d74eb7883c72fb42275fc5358917244
this.lightEngine.updateChunkStatus(ichunkaccess.getPos());
this.lightEngine.tryScheduleUpdate();
-@@ -1260,6 +1314,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -1367,6 +1421,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
asyncSaveData, chunk);
chunk.setUnsaved(false);
@@ -227,7 +226,7 @@ index 6188f35e2b5300b6ff4a16e4d6e0e4a846261f8a..4d74eb7883c72fb42275fc5358917244
}
// Paper end
-@@ -1269,6 +1324,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -1376,6 +1431,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
if (!chunk.isUnsaved()) {
return false;
} else {
@@ -236,10 +235,10 @@ index 6188f35e2b5300b6ff4a16e4d6e0e4a846261f8a..4d74eb7883c72fb42275fc5358917244
ChunkPos chunkcoordintpair = chunk.getPos();
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
-index 1d9a0f6effa1654609f4d0752ec69eed6ab7134b..585892f19bc0aea89889a358c0407f2975b9efe5 100644
+index 70c5e151d47217d417b91105ac63f17a2eb957bf..15b275ee91451478d1c55eae0d20e0e8f36f3a0f 100644
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
-@@ -814,6 +814,15 @@ public class ServerChunkCache extends ChunkSource {
+@@ -668,6 +668,15 @@ public class ServerChunkCache extends ChunkSource {
} // Paper - Timings
}
@@ -256,10 +255,10 @@ index 1d9a0f6effa1654609f4d0752ec69eed6ab7134b..585892f19bc0aea89889a358c0407f29
public void close() throws IOException {
// CraftBukkit start
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index 22a0ca38ae03b8064db7f77dd17335ed4abc72bc..92603bc69e7782f252b2ad7b8c8a4546c9b23e12 100644
+index c9ecc7593c299b351308634db44596a76fd0c09b..8b5eac2ad96c0ebb6eae04585998cade578ff74b 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
-@@ -1085,6 +1085,37 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -1087,6 +1087,37 @@ public class ServerLevel extends Level implements WorldGenLevel {
return !this.server.isUnderSpawnProtection(this, pos, player) && this.getWorldBorder().isWithinBounds(pos);
}
@@ -298,7 +297,7 @@ index 22a0ca38ae03b8064db7f77dd17335ed4abc72bc..92603bc69e7782f252b2ad7b8c8a4546
ServerChunkCache chunkproviderserver = this.getChunkSource();
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
-index 28944fc50ea43a3ea40bd1e69c560c8fe022337e..0720b748ed42bbd2a12cc5de79224f609a5e29be 100644
+index be7d2275548936beade4aba02dc5b14fec95117a..6f2b52165c1935511790a429792d3754251537c8 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -179,6 +179,7 @@ import org.bukkit.inventory.MainHand;
@@ -310,10 +309,10 @@ index 28944fc50ea43a3ea40bd1e69c560c8fe022337e..0720b748ed42bbd2a12cc5de79224f60
private static final int NEUTRAL_MOB_DEATH_NOTIFICATION_RADII_Y = 10;
public ServerGamePacketListenerImpl connection;
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
-index b1f6dc751c3dab5220a02223f6ba205aa0949f84..2ceddd78fb3b69eff60b5cd2b1f42c641f6ecd70 100644
+index 32ab0cd6cb42b0ab8a14f790dfcf4b155c945d6d..1850ce4566e6c5d19140cbf2636b3573f16c4239 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
-@@ -571,6 +571,7 @@ public abstract class PlayerList {
+@@ -569,6 +569,7 @@ public abstract class PlayerList {
protected void save(ServerPlayer player) {
if (!player.getBukkitEntity().isPersistent()) return; // CraftBukkit
if (!player.didPlayerJoinEvent) return; // Paper - If we never fired PJE, we disconnected during login. Data has not changed, and additionally, our saved vehicle is not loaded! If we save now, we will lose our vehicle (CraftBukkit bug)
@@ -321,7 +320,7 @@ index b1f6dc751c3dab5220a02223f6ba205aa0949f84..2ceddd78fb3b69eff60b5cd2b1f42c64
this.playerIo.save(player);
ServerStatsCounter serverstatisticmanager = (ServerStatsCounter) player.getStats(); // CraftBukkit
-@@ -1173,10 +1174,22 @@ public abstract class PlayerList {
+@@ -1171,10 +1172,22 @@ public abstract class PlayerList {
}
public void saveAll() {
@@ -358,7 +357,7 @@ index dc164608bfb2fb18a1adf83fa10bac4028dcac0a..a97909e77b9b28aede8c8716831c3f9a
public static record TicksToSave(SerializableTickContainer<Block> blocks, SerializableTickContainer<Fluid> fluids) {
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
-index 291bcca206722c86bca6d13058d18c413c38d256..f8a3048fa80758d82f2e92d48bd3cd2c585ae6c2 100644
+index c8444f4bfd127b7d8194aaa984505eff249ae094..2981ba61e347b8660082ff946521fc7f219d2c0d 100644
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
@@ -87,6 +87,12 @@ public class LevelChunk extends ChunkAccess {
diff --git a/patches/server/0448-Stop-copy-on-write-operations-for-updating-light-dat.patch b/patches/server/0452-Stop-copy-on-write-operations-for-updating-light-dat.patch
index 74e5860e6b..74e5860e6b 100644
--- a/patches/server/0448-Stop-copy-on-write-operations-for-updating-light-dat.patch
+++ b/patches/server/0452-Stop-copy-on-write-operations-for-updating-light-dat.patch
diff --git a/patches/server/0449-Support-old-UUID-format-for-NBT.patch b/patches/server/0453-Support-old-UUID-format-for-NBT.patch
index 04f6394d7a..04f6394d7a 100644
--- a/patches/server/0449-Support-old-UUID-format-for-NBT.patch
+++ b/patches/server/0453-Support-old-UUID-format-for-NBT.patch
diff --git a/patches/server/0450-Clean-up-duplicated-GameProfile-Properties.patch b/patches/server/0454-Clean-up-duplicated-GameProfile-Properties.patch
index 25554ddf57..25554ddf57 100644
--- a/patches/server/0450-Clean-up-duplicated-GameProfile-Properties.patch
+++ b/patches/server/0454-Clean-up-duplicated-GameProfile-Properties.patch
diff --git a/patches/server/0451-Convert-legacy-attributes-in-Item-Meta.patch b/patches/server/0455-Convert-legacy-attributes-in-Item-Meta.patch
index b949a9e873..b949a9e873 100644
--- a/patches/server/0451-Convert-legacy-attributes-in-Item-Meta.patch
+++ b/patches/server/0455-Convert-legacy-attributes-in-Item-Meta.patch
diff --git a/patches/server/0452-Remove-some-streams-from-structures.patch b/patches/server/0456-Remove-some-streams-from-structures.patch
index d535ed9e91..d535ed9e91 100644
--- a/patches/server/0452-Remove-some-streams-from-structures.patch
+++ b/patches/server/0456-Remove-some-streams-from-structures.patch
diff --git a/patches/server/0453-Remove-streams-from-classes-related-villager-gossip.patch b/patches/server/0457-Remove-streams-from-classes-related-villager-gossip.patch
index b70ae30d26..b70ae30d26 100644
--- a/patches/server/0453-Remove-streams-from-classes-related-villager-gossip.patch
+++ b/patches/server/0457-Remove-streams-from-classes-related-villager-gossip.patch
diff --git a/patches/server/0454-Support-components-in-ItemMeta.patch b/patches/server/0458-Support-components-in-ItemMeta.patch
index 05ab3c1898..05ab3c1898 100644
--- a/patches/server/0454-Support-components-in-ItemMeta.patch
+++ b/patches/server/0458-Support-components-in-ItemMeta.patch
diff --git a/patches/server/0455-Improve-EntityTargetLivingEntityEvent-for-1.16-mobs.patch b/patches/server/0459-Improve-EntityTargetLivingEntityEvent-for-1.16-mobs.patch
index 68a10afd43..68a10afd43 100644
--- a/patches/server/0455-Improve-EntityTargetLivingEntityEvent-for-1.16-mobs.patch
+++ b/patches/server/0459-Improve-EntityTargetLivingEntityEvent-for-1.16-mobs.patch
diff --git a/patches/server/0456-Add-entity-liquid-API.patch b/patches/server/0460-Add-entity-liquid-API.patch
index 91b94fb4dc..0f1072e587 100644
--- a/patches/server/0456-Add-entity-liquid-API.patch
+++ b/patches/server/0460-Add-entity-liquid-API.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] Add entity liquid API
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
-index 6029cb7d8801c471e596ba027b7e408a27c44db9..c0a2cffadb762240ef8fcdec1bd1e49edd3b5c61 100644
+index cd958bc3c00f53ebaf9b3ae39564d3abb6c819a1..863cd2c84dd207f984ddad977e9fd23860247c68 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
@@ -1254,5 +1254,29 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
diff --git a/patches/server/0457-Update-itemstack-legacy-name-and-lore.patch b/patches/server/0461-Update-itemstack-legacy-name-and-lore.patch
index b354241c07..b354241c07 100644
--- a/patches/server/0457-Update-itemstack-legacy-name-and-lore.patch
+++ b/patches/server/0461-Update-itemstack-legacy-name-and-lore.patch
diff --git a/patches/server/0458-Spawn-player-in-correct-world-on-login.patch b/patches/server/0462-Spawn-player-in-correct-world-on-login.patch
index cbcca8f896..a59a3e8562 100644
--- a/patches/server/0458-Spawn-player-in-correct-world-on-login.patch
+++ b/patches/server/0462-Spawn-player-in-correct-world-on-login.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Spawn player in correct world on login
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
-index 20bedb5ce597b8e3e96af910d88137e0a0b10066..559db90e1ba3d636ea080f47cdf274d11a1bcb89 100644
+index 1850ce4566e6c5d19140cbf2636b3573f16c4239..1cb6900489ad25ddd40a3b8c39f436c03a72b3dc 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
-@@ -200,7 +200,18 @@ public abstract class PlayerList {
+@@ -203,7 +203,18 @@ public abstract class PlayerList {
}String lastKnownName = s; // Paper
// CraftBukkit end
diff --git a/patches/server/0459-Add-PrepareResultEvent.patch b/patches/server/0463-Add-PrepareResultEvent.patch
index 415d9409c8..415d9409c8 100644
--- a/patches/server/0459-Add-PrepareResultEvent.patch
+++ b/patches/server/0463-Add-PrepareResultEvent.patch
diff --git a/patches/server/0460-Don-t-check-chunk-for-portal-on-world-gen-entity-add.patch b/patches/server/0464-Don-t-check-chunk-for-portal-on-world-gen-entity-add.patch
index 110614ac67..110614ac67 100644
--- a/patches/server/0460-Don-t-check-chunk-for-portal-on-world-gen-entity-add.patch
+++ b/patches/server/0464-Don-t-check-chunk-for-portal-on-world-gen-entity-add.patch
diff --git a/patches/server/0462-Optimize-NetworkManager-Exception-Handling.patch b/patches/server/0465-Optimize-NetworkManager-Exception-Handling.patch
index cf2905d1ed..cf2905d1ed 100644
--- a/patches/server/0462-Optimize-NetworkManager-Exception-Handling.patch
+++ b/patches/server/0465-Optimize-NetworkManager-Exception-Handling.patch
diff --git a/patches/server/0463-Optimize-the-advancement-data-player-iteration-to-be.patch b/patches/server/0466-Optimize-the-advancement-data-player-iteration-to-be.patch
index 0763953dd5..0763953dd5 100644
--- a/patches/server/0463-Optimize-the-advancement-data-player-iteration-to-be.patch
+++ b/patches/server/0466-Optimize-the-advancement-data-player-iteration-to-be.patch
diff --git a/patches/server/0464-Fix-arrows-never-despawning-MC-125757.patch b/patches/server/0467-Fix-arrows-never-despawning-MC-125757.patch
index 8bdc8589fd..8bdc8589fd 100644
--- a/patches/server/0464-Fix-arrows-never-despawning-MC-125757.patch
+++ b/patches/server/0467-Fix-arrows-never-despawning-MC-125757.patch
diff --git a/patches/server/0465-Thread-Safe-Vanilla-Command-permission-checking.patch b/patches/server/0468-Thread-Safe-Vanilla-Command-permission-checking.patch
index 09b482e662..09b482e662 100644
--- a/patches/server/0465-Thread-Safe-Vanilla-Command-permission-checking.patch
+++ b/patches/server/0468-Thread-Safe-Vanilla-Command-permission-checking.patch
diff --git a/patches/server/0466-Fix-SPIGOT-5989.patch b/patches/server/0469-Fix-SPIGOT-5989.patch
index 9d1324f0e2..111dc3b220 100644
--- a/patches/server/0466-Fix-SPIGOT-5989.patch
+++ b/patches/server/0469-Fix-SPIGOT-5989.patch
@@ -10,10 +10,10 @@ This fixes that by checking if the modified spawn location is
still at a respawn anchor.
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
-index 2700a1337e08727078e52b90b477ff7291c8af8d..0cbfbd9f274974674970def11e5d76ba9e663e16 100644
+index 1cb6900489ad25ddd40a3b8c39f436c03a72b3dc..8fd4494fcd29e92856938792b922ee3ef0102604 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
-@@ -845,6 +845,7 @@ public abstract class PlayerList {
+@@ -842,6 +842,7 @@ public abstract class PlayerList {
// Paper start
boolean isBedSpawn = false;
boolean isRespawn = false;
@@ -21,7 +21,7 @@ index 2700a1337e08727078e52b90b477ff7291c8af8d..0cbfbd9f274974674970def11e5d76ba
// Paper end
// CraftBukkit start - fire PlayerRespawnEvent
-@@ -855,7 +856,7 @@ public abstract class PlayerList {
+@@ -852,7 +853,7 @@ public abstract class PlayerList {
Optional optional;
if (blockposition != null) {
@@ -30,7 +30,7 @@ index 2700a1337e08727078e52b90b477ff7291c8af8d..0cbfbd9f274974674970def11e5d76ba
} else {
optional = Optional.empty();
}
-@@ -899,7 +900,12 @@ public abstract class PlayerList {
+@@ -896,7 +897,12 @@ public abstract class PlayerList {
}
// Spigot End
@@ -44,7 +44,7 @@ index 2700a1337e08727078e52b90b477ff7291c8af8d..0cbfbd9f274974674970def11e5d76ba
if (!flag) entityplayer.reset(); // SPIGOT-4785
isRespawn = true; // Paper
} else {
-@@ -937,8 +943,12 @@ public abstract class PlayerList {
+@@ -934,8 +940,12 @@ public abstract class PlayerList {
}
// entityplayer1.initInventoryMenu();
entityplayer1.setHealth(entityplayer1.getHealth());
diff --git a/patches/server/0467-Fix-SPIGOT-5824-Bukkit-world-container-is-not-used.patch b/patches/server/0470-Fix-SPIGOT-5824-Bukkit-world-container-is-not-used.patch
index 02319f5891..02319f5891 100644
--- a/patches/server/0467-Fix-SPIGOT-5824-Bukkit-world-container-is-not-used.patch
+++ b/patches/server/0470-Fix-SPIGOT-5824-Bukkit-world-container-is-not-used.patch
diff --git a/patches/server/0468-Fix-SPIGOT-5885-Unable-to-disable-advancements.patch b/patches/server/0471-Fix-SPIGOT-5885-Unable-to-disable-advancements.patch
index d18114cb9b..d18114cb9b 100644
--- a/patches/server/0468-Fix-SPIGOT-5885-Unable-to-disable-advancements.patch
+++ b/patches/server/0471-Fix-SPIGOT-5885-Unable-to-disable-advancements.patch
diff --git a/patches/server/0469-Fix-AdvancementDataPlayer-leak-due-from-quitting-ear.patch b/patches/server/0472-Fix-AdvancementDataPlayer-leak-due-from-quitting-ear.patch
index 484c50da0a..484c50da0a 100644
--- a/patches/server/0469-Fix-AdvancementDataPlayer-leak-due-from-quitting-ear.patch
+++ b/patches/server/0472-Fix-AdvancementDataPlayer-leak-due-from-quitting-ear.patch
diff --git a/patches/server/0470-Add-missing-strikeLighting-call-to-World-spigot-stri.patch b/patches/server/0473-Add-missing-strikeLighting-call-to-World-spigot-stri.patch
index 2fc1e0bde7..4c6955f7fd 100644
--- a/patches/server/0470-Add-missing-strikeLighting-call-to-World-spigot-stri.patch
+++ b/patches/server/0473-Add-missing-strikeLighting-call-to-World-spigot-stri.patch
@@ -6,10 +6,10 @@ Subject: [PATCH] Add missing strikeLighting call to
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-index af22fa8aa8ddef4d592564b14d0114cc6f903fca..566636192c8c5858999c80c31b068aeb5bace1e6 100644
+index 710270775cd47e8df1146ad0636648568d45ac75..04896192121039ef6a3be103d59a9d687d7f6c05 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-@@ -2172,6 +2172,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+@@ -2136,6 +2136,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
lightning.moveTo( loc.getX(), loc.getY(), loc.getZ() );
lightning.visualOnly = true;
lightning.isSilent = isSilent;
diff --git a/patches/server/0471-Fix-some-rails-connecting-improperly.patch b/patches/server/0474-Fix-some-rails-connecting-improperly.patch
index 4dc21a2695..4dc21a2695 100644
--- a/patches/server/0471-Fix-some-rails-connecting-improperly.patch
+++ b/patches/server/0474-Fix-some-rails-connecting-improperly.patch
diff --git a/patches/server/0472-Fix-regex-mistake-in-CB-NBT-int-deserialization.patch b/patches/server/0475-Fix-regex-mistake-in-CB-NBT-int-deserialization.patch
index be48fd5ae2..be48fd5ae2 100644
--- a/patches/server/0472-Fix-regex-mistake-in-CB-NBT-int-deserialization.patch
+++ b/patches/server/0475-Fix-regex-mistake-in-CB-NBT-int-deserialization.patch
diff --git a/patches/server/0473-Do-not-let-the-server-load-chunks-from-newer-version.patch b/patches/server/0476-Do-not-let-the-server-load-chunks-from-newer-version.patch
index 6fb1c85c61..6fb1c85c61 100644
--- a/patches/server/0473-Do-not-let-the-server-load-chunks-from-newer-version.patch
+++ b/patches/server/0476-Do-not-let-the-server-load-chunks-from-newer-version.patch
diff --git a/patches/server/0474-Brand-support.patch b/patches/server/0477-Brand-support.patch
index 5cfc2a82a7..1a2c0f5d4b 100644
--- a/patches/server/0474-Brand-support.patch
+++ b/patches/server/0477-Brand-support.patch
@@ -56,10 +56,10 @@ index 487003209da9fce5c365be041a7b9643404bce8e..ecd3d2cb0a4da4360c420f8c733a5898
return (!this.player.joining && !this.connection.isConnected()) || this.processedDisconnect; // Paper
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
-index 8db930d54ad97435e367aa670466d8a072ca0b23..1ab74f26cf47372b89b74a077fe06e48f08581a7 100644
+index 0fda8c27c717bd030b826c5c7267b880f9d1f6b9..10e1be2349df779b911848f70e4b8f0e351b1de7 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
-@@ -2691,6 +2691,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
+@@ -2681,6 +2681,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
// Paper end
};
diff --git a/patches/server/0475-Add-setMaxPlayers-API.patch b/patches/server/0478-Add-setMaxPlayers-API.patch
index d0c4c40d25..0efd813c6f 100644
--- a/patches/server/0475-Add-setMaxPlayers-API.patch
+++ b/patches/server/0478-Add-setMaxPlayers-API.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] Add #setMaxPlayers API
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
-index 8c1b6aa3957a988656eeb2ad6323fdbd2f67cd19..67c50a329e7bdf4056a1217963e29e8ceb99b20f 100644
+index 8fd4494fcd29e92856938792b922ee3ef0102604..ceb5e9540e54275e97f08533d16c820061e76c8f 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -147,7 +147,7 @@ public abstract class PlayerList {
@@ -18,7 +18,7 @@ index 8c1b6aa3957a988656eeb2ad6323fdbd2f67cd19..67c50a329e7bdf4056a1217963e29e8c
private int simulationDistance;
private boolean allowCheatsForAllPlayers;
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-index c7a6143ebb2ed0a0977e1d38c8adcccf09800638..72e545e9aa01ad7ae4180d5421e16e330b4c9934 100644
+index 58f361ad664ba45c496ab0817c7ab5e1a017b807..f156620c14e28513fd0f825d5f34de5c5f831b75 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -674,6 +674,13 @@ public final class CraftServer implements Server {
diff --git a/patches/server/0476-Add-playPickupItemAnimation-to-LivingEntity.patch b/patches/server/0479-Add-playPickupItemAnimation-to-LivingEntity.patch
index 9efead6d4e..9efead6d4e 100644
--- a/patches/server/0476-Add-playPickupItemAnimation-to-LivingEntity.patch
+++ b/patches/server/0479-Add-playPickupItemAnimation-to-LivingEntity.patch
diff --git a/patches/server/0477-Don-t-require-FACING-data.patch b/patches/server/0480-Don-t-require-FACING-data.patch
index fd2ab14906..fd2ab14906 100644
--- a/patches/server/0477-Don-t-require-FACING-data.patch
+++ b/patches/server/0480-Don-t-require-FACING-data.patch
diff --git a/patches/server/0478-Fix-SpawnChangeEvent-not-firing-for-all-use-cases.patch b/patches/server/0481-Fix-SpawnChangeEvent-not-firing-for-all-use-cases.patch
index 2ee7bebf84..79f5aab58a 100644
--- a/patches/server/0478-Fix-SpawnChangeEvent-not-firing-for-all-use-cases.patch
+++ b/patches/server/0481-Fix-SpawnChangeEvent-not-firing-for-all-use-cases.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Fix SpawnChangeEvent not firing for all use-cases
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index 92603bc69e7782f252b2ad7b8c8a4546c9b23e12..0d51a518fa8b5d3ef5f6332c2b8f8796d62da658 100644
+index 8b5eac2ad96c0ebb6eae04585998cade578ff74b..2ba432f7be370ce1a5861e90de9541d76acdcfd2 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
-@@ -1853,6 +1853,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -1855,6 +1855,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
//ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(new BlockPosition(this.worldData.a(), 0, this.worldData.c()));
this.levelData.setSpawn(pos, angle);
@@ -17,10 +17,10 @@ index 92603bc69e7782f252b2ad7b8c8a4546c9b23e12..0d51a518fa8b5d3ef5f6332c2b8f8796
// if this keepSpawnInMemory is false a plugin has already removed our tickets, do not re-add
this.removeTicketsForSpawn(this.paperConfig().spawn.keepSpawnLoadedRange * 16, prevSpawn);
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-index 566636192c8c5858999c80c31b068aeb5bace1e6..a04ae390f2d054b2ad9fb91eca04955471247b5a 100644
+index 04896192121039ef6a3be103d59a9d687d7f6c05..b95aed97b48bf31091ee2f44a21ad88071e97bf3 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-@@ -264,11 +264,13 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+@@ -263,11 +263,13 @@ public class CraftWorld extends CraftRegionAccessor implements World {
public boolean setSpawnLocation(int x, int y, int z, float angle) {
try {
Location previousLocation = this.getSpawnLocation();
diff --git a/patches/server/0479-Add-moon-phase-API.patch b/patches/server/0482-Add-moon-phase-API.patch
index c400ce80c7..c400ce80c7 100644
--- a/patches/server/0479-Add-moon-phase-API.patch
+++ b/patches/server/0482-Add-moon-phase-API.patch
diff --git a/patches/server/0480-Improve-Chunk-Status-Transition-Speed.patch b/patches/server/0483-Improve-Chunk-Status-Transition-Speed.patch
index a4f7a9420d..352e70742e 100644
--- a/patches/server/0480-Improve-Chunk-Status-Transition-Speed.patch
+++ b/patches/server/0483-Improve-Chunk-Status-Transition-Speed.patch
@@ -36,10 +36,10 @@ scenario / path:
Previously would have hopped to SERVER around 12+ times there extra.
diff --git a/src/main/java/net/minecraft/server/level/ChunkHolder.java b/src/main/java/net/minecraft/server/level/ChunkHolder.java
-index ece4cd0de061969d4d2f07560e6cf38e631098b3..90f65fdcc4acf6762c67a5cb3023d2493f03144f 100644
+index ac42029596ae0c824bf33a4058ac1009740e29ea..a699107b1afea1c52e5a7e93af8f39ae9e1955b3 100644
--- a/src/main/java/net/minecraft/server/level/ChunkHolder.java
+++ b/src/main/java/net/minecraft/server/level/ChunkHolder.java
-@@ -95,6 +95,13 @@ public class ChunkHolder {
+@@ -101,6 +101,13 @@ public class ChunkHolder {
// Paper end - optimise anyPlayerCloseEnoughForSpawning
long lastAutoSaveTime; // Paper - incremental autosave
long inactiveTimeStart; // Paper - incremental autosave
@@ -54,10 +54,10 @@ index ece4cd0de061969d4d2f07560e6cf38e631098b3..90f65fdcc4acf6762c67a5cb3023d249
public ChunkHolder(ChunkPos pos, int level, LevelHeightAccessor world, LevelLightEngine lightingProvider, ChunkHolder.LevelChangeListener levelUpdateListener, ChunkHolder.PlayerProvider playersWatchingChunkProvider) {
this.futures = new AtomicReferenceArray(ChunkHolder.CHUNK_STATUSES.size());
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
-index 7b1781faed02a5b5fa37ca6f079d1fb620315c80..b659a058a0b6eb6b1827aacbd703e15fcbb1609c 100644
+index 7493da0f1c3f8ab0ebc517347ef23fbe2747a306..5a78ee69748b2b7b57a9adcff0a4718b1cc0c4ea 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
-@@ -709,7 +709,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -726,7 +726,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
return either.mapLeft((list) -> {
return (LevelChunk) list.get(list.size() / 2);
});
@@ -66,7 +66,7 @@ index 7b1781faed02a5b5fa37ca6f079d1fb620315c80..b659a058a0b6eb6b1827aacbd703e15f
}
@Nullable
-@@ -1115,6 +1115,12 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -1144,6 +1144,12 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
return "chunkGenerate " + requiredStatus.getName();
});
Executor executor = (runnable) -> {
diff --git a/patches/server/0481-Prevent-headless-pistons-from-being-created.patch b/patches/server/0484-Prevent-headless-pistons-from-being-created.patch
index b31a2a9b3a..b31a2a9b3a 100644
--- a/patches/server/0481-Prevent-headless-pistons-from-being-created.patch
+++ b/patches/server/0484-Prevent-headless-pistons-from-being-created.patch
diff --git a/patches/server/0482-Add-BellRingEvent.patch b/patches/server/0485-Add-BellRingEvent.patch
index e6528721cf..e6528721cf 100644
--- a/patches/server/0482-Add-BellRingEvent.patch
+++ b/patches/server/0485-Add-BellRingEvent.patch
diff --git a/patches/server/0483-Add-zombie-targets-turtle-egg-config.patch b/patches/server/0486-Add-zombie-targets-turtle-egg-config.patch
index a92287451d..a92287451d 100644
--- a/patches/server/0483-Add-zombie-targets-turtle-egg-config.patch
+++ b/patches/server/0486-Add-zombie-targets-turtle-egg-config.patch
diff --git a/patches/server/0484-Buffer-joins-to-world.patch b/patches/server/0487-Buffer-joins-to-world.patch
index f21684f9df..f21684f9df 100644
--- a/patches/server/0484-Buffer-joins-to-world.patch
+++ b/patches/server/0487-Buffer-joins-to-world.patch
diff --git a/patches/server/0485-Eigencraft-redstone-implementation.patch b/patches/server/0488-Eigencraft-redstone-implementation.patch
index e4a4e5398a..e4a4e5398a 100644
--- a/patches/server/0485-Eigencraft-redstone-implementation.patch
+++ b/patches/server/0488-Eigencraft-redstone-implementation.patch
diff --git a/patches/server/0486-Fix-hex-colors-not-working-in-some-kick-messages.patch b/patches/server/0489-Fix-hex-colors-not-working-in-some-kick-messages.patch
index c4f76a0ad7..c4f76a0ad7 100644
--- a/patches/server/0486-Fix-hex-colors-not-working-in-some-kick-messages.patch
+++ b/patches/server/0489-Fix-hex-colors-not-working-in-some-kick-messages.patch
diff --git a/patches/server/0487-PortalCreateEvent-needs-to-know-its-entity.patch b/patches/server/0490-PortalCreateEvent-needs-to-know-its-entity.patch
index 3c2cb7d994..3c2cb7d994 100644
--- a/patches/server/0487-PortalCreateEvent-needs-to-know-its-entity.patch
+++ b/patches/server/0490-PortalCreateEvent-needs-to-know-its-entity.patch
diff --git a/patches/server/0488-Fix-CraftTeam-null-check.patch b/patches/server/0491-Fix-CraftTeam-null-check.patch
index fc8ca37076..fc8ca37076 100644
--- a/patches/server/0488-Fix-CraftTeam-null-check.patch
+++ b/patches/server/0491-Fix-CraftTeam-null-check.patch
diff --git a/patches/server/0489-Add-more-Evoker-API.patch b/patches/server/0492-Add-more-Evoker-API.patch
index 367e900e25..367e900e25 100644
--- a/patches/server/0489-Add-more-Evoker-API.patch
+++ b/patches/server/0492-Add-more-Evoker-API.patch
diff --git a/patches/server/0490-Add-methods-to-get-translation-keys.patch b/patches/server/0493-Add-methods-to-get-translation-keys.patch
index 5a5b0a4cd6..5a5b0a4cd6 100644
--- a/patches/server/0490-Add-methods-to-get-translation-keys.patch
+++ b/patches/server/0493-Add-methods-to-get-translation-keys.patch
diff --git a/patches/server/0491-Create-HoverEvent-from-ItemStack-Entity.patch b/patches/server/0494-Create-HoverEvent-from-ItemStack-Entity.patch
index 238466b430..238466b430 100644
--- a/patches/server/0491-Create-HoverEvent-from-ItemStack-Entity.patch
+++ b/patches/server/0494-Create-HoverEvent-from-ItemStack-Entity.patch
diff --git a/patches/server/0492-Cache-block-data-strings.patch b/patches/server/0495-Cache-block-data-strings.patch
index 6258b9db9a..6258b9db9a 100644
--- a/patches/server/0492-Cache-block-data-strings.patch
+++ b/patches/server/0495-Cache-block-data-strings.patch
diff --git a/patches/server/0493-Fix-Entity-Teleportation-and-cancel-velocity-if-tele.patch b/patches/server/0496-Fix-Entity-Teleportation-and-cancel-velocity-if-tele.patch
index efcb3aac9e..66b1d24e2d 100644
--- a/patches/server/0493-Fix-Entity-Teleportation-and-cancel-velocity-if-tele.patch
+++ b/patches/server/0496-Fix-Entity-Teleportation-and-cancel-velocity-if-tele.patch
@@ -69,10 +69,10 @@ index e3d8814cbad30da795632afddf8ebc87eff72106..ee619590aa49323059947fbaee9e88d6
if (entity instanceof Mob) {
Mob entityinsentient = (Mob) entity;
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
-index c0a2cffadb762240ef8fcdec1bd1e49edd3b5c61..148cd01c88600042c557f21558acace8bfdfa1cf 100644
+index 863cd2c84dd207f984ddad977e9fd23860247c68..ab270a14263d6a264bb74de3b924584ac41ed523 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
-@@ -590,7 +590,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
+@@ -559,7 +559,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
}
// entity.setLocation() throws no event, and so cannot be cancelled
diff --git a/patches/server/0494-Add-additional-open-container-api-to-HumanEntity.patch b/patches/server/0497-Add-additional-open-container-api-to-HumanEntity.patch
index 53f2348da6..53f2348da6 100644
--- a/patches/server/0494-Add-additional-open-container-api-to-HumanEntity.patch
+++ b/patches/server/0497-Add-additional-open-container-api-to-HumanEntity.patch
diff --git a/patches/server/0495-Cache-DataFixerUpper-Rewrite-Rules-on-demand.patch b/patches/server/0498-Cache-DataFixerUpper-Rewrite-Rules-on-demand.patch
index 602cc3a878..602cc3a878 100644
--- a/patches/server/0495-Cache-DataFixerUpper-Rewrite-Rules-on-demand.patch
+++ b/patches/server/0498-Cache-DataFixerUpper-Rewrite-Rules-on-demand.patch
diff --git a/patches/server/0496-Extend-block-drop-capture-to-capture-all-items-added.patch b/patches/server/0499-Extend-block-drop-capture-to-capture-all-items-added.patch
index 0c2984a117..9009d631f8 100644
--- a/patches/server/0496-Extend-block-drop-capture-to-capture-all-items-added.patch
+++ b/patches/server/0499-Extend-block-drop-capture-to-capture-all-items-added.patch
@@ -6,10 +6,10 @@ Subject: [PATCH] Extend block drop capture to capture all items added to the
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index 0d51a518fa8b5d3ef5f6332c2b8f8796d62da658..d78b75d00ff95eb0c9619420c2921881724d8561 100644
+index 2ba432f7be370ce1a5861e90de9541d76acdcfd2..85c0a80f00f5968b684b3609fbe56197e4aeb202 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
-@@ -1290,6 +1290,12 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -1292,6 +1292,12 @@ public class ServerLevel extends Level implements WorldGenLevel {
// WorldServer.LOGGER.warn("Tried to add entity {} but it was marked as removed already", EntityTypes.getKey(entity.getType())); // CraftBukkit
return false;
} else {
diff --git a/patches/server/0497-Don-t-mark-dirty-in-invalid-locations-SPIGOT-6086.patch b/patches/server/0500-Don-t-mark-dirty-in-invalid-locations-SPIGOT-6086.patch
index e3de5bc8a4..89aadfda9c 100644
--- a/patches/server/0497-Don-t-mark-dirty-in-invalid-locations-SPIGOT-6086.patch
+++ b/patches/server/0500-Don-t-mark-dirty-in-invalid-locations-SPIGOT-6086.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Don't mark dirty in invalid locations (SPIGOT-6086)
diff --git a/src/main/java/net/minecraft/server/level/ChunkHolder.java b/src/main/java/net/minecraft/server/level/ChunkHolder.java
-index 90f65fdcc4acf6762c67a5cb3023d2493f03144f..96fb6e6ba3d1f9d5bd412f4f2bfb9450efa17948 100644
+index a699107b1afea1c52e5a7e93af8f39ae9e1955b3..c4046b364d1896b781e23c92b241ec73c239d3a0 100644
--- a/src/main/java/net/minecraft/server/level/ChunkHolder.java
+++ b/src/main/java/net/minecraft/server/level/ChunkHolder.java
-@@ -245,6 +245,7 @@ public class ChunkHolder {
+@@ -250,6 +250,7 @@ public class ChunkHolder {
}
public void blockChanged(BlockPos pos) {
diff --git a/patches/server/0498-Expose-the-Entity-Counter-to-allow-plugins-to-use-va.patch b/patches/server/0501-Expose-the-Entity-Counter-to-allow-plugins-to-use-va.patch
index be65d53303..be65d53303 100644
--- a/patches/server/0498-Expose-the-Entity-Counter-to-allow-plugins-to-use-va.patch
+++ b/patches/server/0501-Expose-the-Entity-Counter-to-allow-plugins-to-use-va.patch
diff --git a/patches/server/0499-Lazily-track-plugin-scoreboards-by-default.patch b/patches/server/0502-Lazily-track-plugin-scoreboards-by-default.patch
index bb0fe1c990..bb0fe1c990 100644
--- a/patches/server/0499-Lazily-track-plugin-scoreboards-by-default.patch
+++ b/patches/server/0502-Lazily-track-plugin-scoreboards-by-default.patch
diff --git a/patches/server/0500-Entity-isTicking.patch b/patches/server/0503-Entity-isTicking.patch
index c2e18c0dd7..86502ef7ae 100644
--- a/patches/server/0500-Entity-isTicking.patch
+++ b/patches/server/0503-Entity-isTicking.patch
@@ -27,7 +27,7 @@ index 511255467688d4c9397037753d2d4821af29bb79..532678194c2724e31a19f0e4d73d79d8
// Paper end
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
-index 148cd01c88600042c557f21558acace8bfdfa1cf..c39b683cbe83618daee0ca00d1107b115af6bf8f 100644
+index ab270a14263d6a264bb74de3b924584ac41ed523..fa1e996157fb3470c08669801e7482af70714b11 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
@@ -1278,5 +1278,9 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
diff --git a/patches/server/0501-Fix-deop-kicking-non-whitelisted-player-when-white-l.patch b/patches/server/0504-Fix-deop-kicking-non-whitelisted-player-when-white-l.patch
index 2af120114e..2af120114e 100644
--- a/patches/server/0501-Fix-deop-kicking-non-whitelisted-player-when-white-l.patch
+++ b/patches/server/0504-Fix-deop-kicking-non-whitelisted-player-when-white-l.patch
diff --git a/patches/server/0502-Fix-Concurrency-issue-in-ShufflingList.patch b/patches/server/0505-Fix-Concurrency-issue-in-ShufflingList.patch
index 5b3dba224c..5b3dba224c 100644
--- a/patches/server/0502-Fix-Concurrency-issue-in-ShufflingList.patch
+++ b/patches/server/0505-Fix-Concurrency-issue-in-ShufflingList.patch
diff --git a/patches/server/0503-Reset-Ender-Crystals-on-Dragon-Spawn.patch b/patches/server/0506-Reset-Ender-Crystals-on-Dragon-Spawn.patch
index 31cde5ee93..31cde5ee93 100644
--- a/patches/server/0503-Reset-Ender-Crystals-on-Dragon-Spawn.patch
+++ b/patches/server/0506-Reset-Ender-Crystals-on-Dragon-Spawn.patch
diff --git a/patches/server/0504-Fix-for-large-move-vectors-crashing-server.patch b/patches/server/0507-Fix-for-large-move-vectors-crashing-server.patch
index 415947895c..415947895c 100644
--- a/patches/server/0504-Fix-for-large-move-vectors-crashing-server.patch
+++ b/patches/server/0507-Fix-for-large-move-vectors-crashing-server.patch
diff --git a/patches/server/0505-Optimise-getType-calls.patch b/patches/server/0508-Optimise-getType-calls.patch
index 5d53107ff2..5d53107ff2 100644
--- a/patches/server/0505-Optimise-getType-calls.patch
+++ b/patches/server/0508-Optimise-getType-calls.patch
diff --git a/patches/server/0506-Villager-resetOffers.patch b/patches/server/0509-Villager-resetOffers.patch
index 7448270230..7448270230 100644
--- a/patches/server/0506-Villager-resetOffers.patch
+++ b/patches/server/0509-Villager-resetOffers.patch
diff --git a/patches/server/0507-Improve-inlinig-for-some-hot-IBlockData-methods.patch b/patches/server/0510-Improve-inlinig-for-some-hot-IBlockData-methods.patch
index 3639390300..3639390300 100644
--- a/patches/server/0507-Improve-inlinig-for-some-hot-IBlockData-methods.patch
+++ b/patches/server/0510-Improve-inlinig-for-some-hot-IBlockData-methods.patch
diff --git a/patches/server/0508-Retain-block-place-order-when-capturing-blockstates.patch b/patches/server/0511-Retain-block-place-order-when-capturing-blockstates.patch
index ae8ed41c93..ae8ed41c93 100644
--- a/patches/server/0508-Retain-block-place-order-when-capturing-blockstates.patch
+++ b/patches/server/0511-Retain-block-place-order-when-capturing-blockstates.patch
diff --git a/patches/server/0509-Reduce-blockpos-allocation-from-pathfinding.patch b/patches/server/0512-Reduce-blockpos-allocation-from-pathfinding.patch
index 3f620bf4e9..3f620bf4e9 100644
--- a/patches/server/0509-Reduce-blockpos-allocation-from-pathfinding.patch
+++ b/patches/server/0512-Reduce-blockpos-allocation-from-pathfinding.patch
diff --git a/patches/server/0510-Fix-item-locations-dropped-from-campfires.patch b/patches/server/0513-Fix-item-locations-dropped-from-campfires.patch
index df944d4a66..df944d4a66 100644
--- a/patches/server/0510-Fix-item-locations-dropped-from-campfires.patch
+++ b/patches/server/0513-Fix-item-locations-dropped-from-campfires.patch
diff --git a/patches/server/0511-Player-elytra-boost-API.patch b/patches/server/0514-Player-elytra-boost-API.patch
index 54561c48a1..1e60420c04 100644
--- a/patches/server/0511-Player-elytra-boost-API.patch
+++ b/patches/server/0514-Player-elytra-boost-API.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] Player elytra boost API
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
-index 03d43fdc119dc526928abf7b0f1b38d35e985ffc..fb4f868457ebf06b26ddc60f5ffc5a1d5273a1bc 100644
+index 10e1be2349df779b911848f70e4b8f0e351b1de7..09f5a288cba1825fa0fff32f771f98675f473527 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -592,6 +592,20 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
diff --git a/patches/server/0512-Fixed-TileEntityBell-memory-leak.patch b/patches/server/0515-Fixed-TileEntityBell-memory-leak.patch
index 09d0b77f4a..09d0b77f4a 100644
--- a/patches/server/0512-Fixed-TileEntityBell-memory-leak.patch
+++ b/patches/server/0515-Fixed-TileEntityBell-memory-leak.patch
diff --git a/patches/server/0513-Avoid-error-bubbling-up-when-item-stack-is-empty-in-.patch b/patches/server/0516-Avoid-error-bubbling-up-when-item-stack-is-empty-in-.patch
index f48528d0b5..f48528d0b5 100644
--- a/patches/server/0513-Avoid-error-bubbling-up-when-item-stack-is-empty-in-.patch
+++ b/patches/server/0516-Avoid-error-bubbling-up-when-item-stack-is-empty-in-.patch
diff --git a/patches/server/0514-Add-getOfflinePlayerIfCached-String.patch b/patches/server/0517-Add-getOfflinePlayerIfCached-String.patch
index 683ca40784..b453ab0746 100644
--- a/patches/server/0514-Add-getOfflinePlayerIfCached-String.patch
+++ b/patches/server/0517-Add-getOfflinePlayerIfCached-String.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] Add getOfflinePlayerIfCached(String)
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-index 72e545e9aa01ad7ae4180d5421e16e330b4c9934..f5ed17af815f2e7da523e80319dc4021556376b2 100644
+index f156620c14e28513fd0f825d5f34de5c5f831b75..f5783a0df00c7c88c5d5d1c3b55ba671350cd0c6 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -1803,6 +1803,28 @@ public final class CraftServer implements Server {
diff --git a/patches/server/0515-Add-ignore-discounts-API.patch b/patches/server/0518-Add-ignore-discounts-API.patch
index e77eb448c9..e77eb448c9 100644
--- a/patches/server/0515-Add-ignore-discounts-API.patch
+++ b/patches/server/0518-Add-ignore-discounts-API.patch
diff --git a/patches/server/0516-Toggle-for-removing-existing-dragon.patch b/patches/server/0519-Toggle-for-removing-existing-dragon.patch
index 157073f779..157073f779 100644
--- a/patches/server/0516-Toggle-for-removing-existing-dragon.patch
+++ b/patches/server/0519-Toggle-for-removing-existing-dragon.patch
diff --git a/patches/server/0517-Fix-client-lag-on-advancement-loading.patch b/patches/server/0520-Fix-client-lag-on-advancement-loading.patch
index 3c62dff076..3c62dff076 100644
--- a/patches/server/0517-Fix-client-lag-on-advancement-loading.patch
+++ b/patches/server/0520-Fix-client-lag-on-advancement-loading.patch
diff --git a/patches/server/0518-Item-no-age-no-player-pickup.patch b/patches/server/0521-Item-no-age-no-player-pickup.patch
index 13b456555a..13b456555a 100644
--- a/patches/server/0518-Item-no-age-no-player-pickup.patch
+++ b/patches/server/0521-Item-no-age-no-player-pickup.patch
diff --git a/patches/server/0519-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch b/patches/server/0522-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch
index 91c966567f..91c966567f 100644
--- a/patches/server/0519-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch
+++ b/patches/server/0522-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch
diff --git a/patches/server/0520-Beacon-API-custom-effect-ranges.patch b/patches/server/0523-Beacon-API-custom-effect-ranges.patch
index 42125ab17d..42125ab17d 100644
--- a/patches/server/0520-Beacon-API-custom-effect-ranges.patch
+++ b/patches/server/0523-Beacon-API-custom-effect-ranges.patch
diff --git a/patches/server/0521-Add-API-for-quit-reason.patch b/patches/server/0524-Add-API-for-quit-reason.patch
index a632927b3b..20ba1338d0 100644
--- a/patches/server/0521-Add-API-for-quit-reason.patch
+++ b/patches/server/0524-Add-API-for-quit-reason.patch
@@ -49,10 +49,10 @@ index 3b422cd28b3fb8a172a734e3d59636b293d4a5cb..a6820c2262dd2198b772eae491c40ee3
this.connection.disconnect(ichatbasecomponent);
}));
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
-index c00922556462a18543975f7f9c60ea6727e9b114..10acd0256cbe5393b3736be33a55285b7f214a5d 100644
+index ceb5e9540e54275e97f08533d16c820061e76c8f..1d7a7a2d11f0524ae7a81fc0e3bdddd72f5ef53c 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
-@@ -610,7 +610,7 @@ public abstract class PlayerList {
+@@ -607,7 +607,7 @@ public abstract class PlayerList {
entityplayer.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.DISCONNECT); // Paper
}
diff --git a/patches/server/0522-Add-Wandering-Trader-spawn-rate-config-options.patch b/patches/server/0525-Add-Wandering-Trader-spawn-rate-config-options.patch
index a5adffed4f..a5adffed4f 100644
--- a/patches/server/0522-Add-Wandering-Trader-spawn-rate-config-options.patch
+++ b/patches/server/0525-Add-Wandering-Trader-spawn-rate-config-options.patch
diff --git a/patches/server/0523-Expose-world-spawn-angle.patch b/patches/server/0526-Expose-world-spawn-angle.patch
index 1626858a0e..5bf390c16c 100644
--- a/patches/server/0523-Expose-world-spawn-angle.patch
+++ b/patches/server/0526-Expose-world-spawn-angle.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Expose world spawn angle
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
-index 10acd0256cbe5393b3736be33a55285b7f214a5d..2fc183222e539e66c050e146c784a66222dee419 100644
+index 1d7a7a2d11f0524ae7a81fc0e3bdddd72f5ef53c..195fcf93c46967e14a3247768a575c7a73bf9e31 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
-@@ -888,7 +888,7 @@ public abstract class PlayerList {
+@@ -885,7 +885,7 @@ public abstract class PlayerList {
if (location == null) {
worldserver1 = this.server.getLevel(Level.OVERWORLD);
blockposition = entityplayer1.getSpawnPoint(worldserver1);
diff --git a/patches/server/0524-Add-Destroy-Speed-API.patch b/patches/server/0527-Add-Destroy-Speed-API.patch
index a2b7640fee..a2b7640fee 100644
--- a/patches/server/0524-Add-Destroy-Speed-API.patch
+++ b/patches/server/0527-Add-Destroy-Speed-API.patch
diff --git a/patches/server/0525-Fix-Player-spawnParticle-x-y-z-precision-loss.patch b/patches/server/0528-Fix-Player-spawnParticle-x-y-z-precision-loss.patch
index f5ae3e4907..c8c87f141b 100644
--- a/patches/server/0525-Fix-Player-spawnParticle-x-y-z-precision-loss.patch
+++ b/patches/server/0528-Fix-Player-spawnParticle-x-y-z-precision-loss.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Fix Player spawnParticle x/y/z precision loss
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
-index fb4f868457ebf06b26ddc60f5ffc5a1d5273a1bc..4c7d84a8f0f186dba18dba528ed324a0808605e3 100644
+index 09f5a288cba1825fa0fff32f771f98675f473527..21f413b1e75c15fae888a4e6dccefbe822ad1c40 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
-@@ -2273,7 +2273,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
+@@ -2263,7 +2263,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
if (data != null && !particle.getDataType().isInstance(data)) {
throw new IllegalArgumentException("data should be " + particle.getDataType() + " got " + data.getClass());
}
diff --git a/patches/server/0526-Add-LivingEntity-clearActiveItem.patch b/patches/server/0529-Add-LivingEntity-clearActiveItem.patch
index 6b43687673..6b43687673 100644
--- a/patches/server/0526-Add-LivingEntity-clearActiveItem.patch
+++ b/patches/server/0529-Add-LivingEntity-clearActiveItem.patch
diff --git a/patches/server/0527-Add-PlayerItemCooldownEvent.patch b/patches/server/0530-Add-PlayerItemCooldownEvent.patch
index 751841d117..751841d117 100644
--- a/patches/server/0527-Add-PlayerItemCooldownEvent.patch
+++ b/patches/server/0530-Add-PlayerItemCooldownEvent.patch
diff --git a/patches/server/0528-Significantly-improve-performance-of-the-end-generat.patch b/patches/server/0531-Significantly-improve-performance-of-the-end-generat.patch
index c223e5c115..c223e5c115 100644
--- a/patches/server/0528-Significantly-improve-performance-of-the-end-generat.patch
+++ b/patches/server/0531-Significantly-improve-performance-of-the-end-generat.patch
diff --git a/patches/server/0529-More-lightning-API.patch b/patches/server/0532-More-lightning-API.patch
index 142479579e..142479579e 100644
--- a/patches/server/0529-More-lightning-API.patch
+++ b/patches/server/0532-More-lightning-API.patch
diff --git a/patches/server/0530-Climbing-should-not-bypass-cramming-gamerule.patch b/patches/server/0533-Climbing-should-not-bypass-cramming-gamerule.patch
index 50b7fcd2d3..50b7fcd2d3 100644
--- a/patches/server/0530-Climbing-should-not-bypass-cramming-gamerule.patch
+++ b/patches/server/0533-Climbing-should-not-bypass-cramming-gamerule.patch
diff --git a/patches/server/0531-Added-missing-default-perms-for-commands.patch b/patches/server/0534-Added-missing-default-perms-for-commands.patch
index ddaf0c6aec..ddaf0c6aec 100644
--- a/patches/server/0531-Added-missing-default-perms-for-commands.patch
+++ b/patches/server/0534-Added-missing-default-perms-for-commands.patch
diff --git a/patches/server/0532-Add-PlayerShearBlockEvent.patch b/patches/server/0535-Add-PlayerShearBlockEvent.patch
index 4004036b95..4004036b95 100644
--- a/patches/server/0532-Add-PlayerShearBlockEvent.patch
+++ b/patches/server/0535-Add-PlayerShearBlockEvent.patch
diff --git a/patches/server/0533-Fix-curing-zombie-villager-discount-exploit.patch b/patches/server/0536-Fix-curing-zombie-villager-discount-exploit.patch
index c6cb27bebe..c6cb27bebe 100644
--- a/patches/server/0533-Fix-curing-zombie-villager-discount-exploit.patch
+++ b/patches/server/0536-Fix-curing-zombie-villager-discount-exploit.patch
diff --git a/patches/server/0534-Limit-recipe-packets.patch b/patches/server/0537-Limit-recipe-packets.patch
index e2c1e0ee69..e2c1e0ee69 100644
--- a/patches/server/0534-Limit-recipe-packets.patch
+++ b/patches/server/0537-Limit-recipe-packets.patch
diff --git a/patches/server/0535-Fix-CraftSound-backwards-compatibility.patch b/patches/server/0538-Fix-CraftSound-backwards-compatibility.patch
index 60e8ef1e6b..60e8ef1e6b 100644
--- a/patches/server/0535-Fix-CraftSound-backwards-compatibility.patch
+++ b/patches/server/0538-Fix-CraftSound-backwards-compatibility.patch
diff --git a/patches/server/0536-Player-Chunk-Load-Unload-Events.patch b/patches/server/0539-Player-Chunk-Load-Unload-Events.patch
index 04505672a2..04505672a2 100644
--- a/patches/server/0536-Player-Chunk-Load-Unload-Events.patch
+++ b/patches/server/0539-Player-Chunk-Load-Unload-Events.patch
diff --git a/patches/server/0537-Optimize-Dynamic-get-Missing-Keys.patch b/patches/server/0540-Optimize-Dynamic-get-Missing-Keys.patch
index 5a4efe035c..5a4efe035c 100644
--- a/patches/server/0537-Optimize-Dynamic-get-Missing-Keys.patch
+++ b/patches/server/0540-Optimize-Dynamic-get-Missing-Keys.patch
diff --git a/patches/server/0538-Expose-LivingEntity-hurt-direction.patch b/patches/server/0541-Expose-LivingEntity-hurt-direction.patch
index 2f461711f6..2f461711f6 100644
--- a/patches/server/0538-Expose-LivingEntity-hurt-direction.patch
+++ b/patches/server/0541-Expose-LivingEntity-hurt-direction.patch
diff --git a/patches/server/0539-Add-OBSTRUCTED-reason-to-BedEnterResult.patch b/patches/server/0542-Add-OBSTRUCTED-reason-to-BedEnterResult.patch
index 5c4a714385..5c4a714385 100644
--- a/patches/server/0539-Add-OBSTRUCTED-reason-to-BedEnterResult.patch
+++ b/patches/server/0542-Add-OBSTRUCTED-reason-to-BedEnterResult.patch
diff --git a/patches/server/0540-Do-not-crash-from-invalid-ingredient-lists-in-Villag.patch b/patches/server/0543-Do-not-crash-from-invalid-ingredient-lists-in-Villag.patch
index a66e8fc14d..a66e8fc14d 100644
--- a/patches/server/0540-Do-not-crash-from-invalid-ingredient-lists-in-Villag.patch
+++ b/patches/server/0543-Do-not-crash-from-invalid-ingredient-lists-in-Villag.patch
diff --git a/patches/server/0541-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch b/patches/server/0544-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch
index 339a34391b..339a34391b 100644
--- a/patches/server/0541-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch
+++ b/patches/server/0544-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch
diff --git a/patches/server/0542-Implement-TargetHitEvent.patch b/patches/server/0545-Implement-TargetHitEvent.patch
index 78722933d9..78722933d9 100644
--- a/patches/server/0542-Implement-TargetHitEvent.patch
+++ b/patches/server/0545-Implement-TargetHitEvent.patch
diff --git a/patches/server/0543-MC-4-Fix-item-position-desync.patch b/patches/server/0546-MC-4-Fix-item-position-desync.patch
index 4172d387c4..4172d387c4 100644
--- a/patches/server/0543-MC-4-Fix-item-position-desync.patch
+++ b/patches/server/0546-MC-4-Fix-item-position-desync.patch
diff --git a/patches/server/0544-Additional-Block-Material-API-s.patch b/patches/server/0547-Additional-Block-Material-API-s.patch
index e93239aae5..e93239aae5 100644
--- a/patches/server/0544-Additional-Block-Material-API-s.patch
+++ b/patches/server/0547-Additional-Block-Material-API-s.patch
diff --git a/patches/server/0545-Fix-harming-potion-dupe.patch b/patches/server/0548-Fix-harming-potion-dupe.patch
index d131d6c979..d131d6c979 100644
--- a/patches/server/0545-Fix-harming-potion-dupe.patch
+++ b/patches/server/0548-Fix-harming-potion-dupe.patch
diff --git a/patches/server/0546-Implement-API-to-get-Material-from-Boats-and-Minecar.patch b/patches/server/0549-Implement-API-to-get-Material-from-Boats-and-Minecar.patch
index b68431ed82..b68431ed82 100644
--- a/patches/server/0546-Implement-API-to-get-Material-from-Boats-and-Minecar.patch
+++ b/patches/server/0549-Implement-API-to-get-Material-from-Boats-and-Minecar.patch
diff --git a/patches/server/0547-Cache-burn-durations.patch b/patches/server/0550-Cache-burn-durations.patch
index 35387cbe57..35387cbe57 100644
--- a/patches/server/0547-Cache-burn-durations.patch
+++ b/patches/server/0550-Cache-burn-durations.patch
diff --git a/patches/server/0548-Allow-disabling-mob-spawner-spawn-egg-transformation.patch b/patches/server/0551-Allow-disabling-mob-spawner-spawn-egg-transformation.patch
index b11735c5d7..b11735c5d7 100644
--- a/patches/server/0548-Allow-disabling-mob-spawner-spawn-egg-transformation.patch
+++ b/patches/server/0551-Allow-disabling-mob-spawner-spawn-egg-transformation.patch
diff --git a/patches/server/0549-Fix-Not-a-string-Map-Conversion-spam.patch b/patches/server/0552-Fix-Not-a-string-Map-Conversion-spam.patch
index 8967f3f735..8967f3f735 100644
--- a/patches/server/0549-Fix-Not-a-string-Map-Conversion-spam.patch
+++ b/patches/server/0552-Fix-Not-a-string-Map-Conversion-spam.patch
diff --git a/patches/server/0550-Implement-PlayerFlowerPotManipulateEvent.patch b/patches/server/0553-Implement-PlayerFlowerPotManipulateEvent.patch
index 8f512f54d6..8f512f54d6 100644
--- a/patches/server/0550-Implement-PlayerFlowerPotManipulateEvent.patch
+++ b/patches/server/0553-Implement-PlayerFlowerPotManipulateEvent.patch
diff --git a/patches/server/0551-Fix-interact-event-not-being-called-in-adventure.patch b/patches/server/0554-Fix-interact-event-not-being-called-in-adventure.patch
index ff22b7462a..ff22b7462a 100644
--- a/patches/server/0551-Fix-interact-event-not-being-called-in-adventure.patch
+++ b/patches/server/0554-Fix-interact-event-not-being-called-in-adventure.patch
diff --git a/patches/server/0552-Zombie-API-breaking-doors.patch b/patches/server/0555-Zombie-API-breaking-doors.patch
index b89994b417..b89994b417 100644
--- a/patches/server/0552-Zombie-API-breaking-doors.patch
+++ b/patches/server/0555-Zombie-API-breaking-doors.patch
diff --git a/patches/server/0553-Fix-nerfed-slime-when-splitting.patch b/patches/server/0556-Fix-nerfed-slime-when-splitting.patch
index 726d362dff..726d362dff 100644
--- a/patches/server/0553-Fix-nerfed-slime-when-splitting.patch
+++ b/patches/server/0556-Fix-nerfed-slime-when-splitting.patch
diff --git a/patches/server/0554-Add-EntityLoadCrossbowEvent.patch b/patches/server/0557-Add-EntityLoadCrossbowEvent.patch
index 6ffab47e6e..6ffab47e6e 100644
--- a/patches/server/0554-Add-EntityLoadCrossbowEvent.patch
+++ b/patches/server/0557-Add-EntityLoadCrossbowEvent.patch
diff --git a/patches/server/0555-Guardian-beam-workaround.patch b/patches/server/0558-Guardian-beam-workaround.patch
index fa66573d2b..fa66573d2b 100644
--- a/patches/server/0555-Guardian-beam-workaround.patch
+++ b/patches/server/0558-Guardian-beam-workaround.patch
diff --git a/patches/server/0556-Added-WorldGameRuleChangeEvent.patch b/patches/server/0559-Added-WorldGameRuleChangeEvent.patch
index 34d10452cc..86de4a1af6 100644
--- a/patches/server/0556-Added-WorldGameRuleChangeEvent.patch
+++ b/patches/server/0559-Added-WorldGameRuleChangeEvent.patch
@@ -64,10 +64,10 @@ index 800325a544bb9f228ccbeb0a52d7f380a8c6083e..3c93bfeb94168f832904a8462ae23b06
public int get() {
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-index a04ae390f2d054b2ad9fb91eca04955471247b5a..da84c3106b9e6210e234585fdd9eb75e1db041f5 100644
+index b95aed97b48bf31091ee2f44a21ad88071e97bf3..42423b020f9c2ef2ba025b444be076c38314c721 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-@@ -1804,8 +1804,13 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+@@ -1803,8 +1803,13 @@ public class CraftWorld extends CraftRegionAccessor implements World {
if (!this.isGameRule(rule)) return false;
@@ -82,7 +82,7 @@ index a04ae390f2d054b2ad9fb91eca04955471247b5a..da84c3106b9e6210e234585fdd9eb75e
handle.onChanged(this.getHandle().getServer());
return true;
}
-@@ -1840,8 +1845,12 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+@@ -1839,8 +1844,12 @@ public class CraftWorld extends CraftRegionAccessor implements World {
if (!this.isGameRule(rule.getName())) return false;
diff --git a/patches/server/0557-Added-ServerResourcesReloadedEvent.patch b/patches/server/0560-Added-ServerResourcesReloadedEvent.patch
index d030c34c58..d030c34c58 100644
--- a/patches/server/0557-Added-ServerResourcesReloadedEvent.patch
+++ b/patches/server/0560-Added-ServerResourcesReloadedEvent.patch
diff --git a/patches/server/0558-Added-world-settings-for-mobs-picking-up-loot.patch b/patches/server/0561-Added-world-settings-for-mobs-picking-up-loot.patch
index 4c1e7b2549..4c1e7b2549 100644
--- a/patches/server/0558-Added-world-settings-for-mobs-picking-up-loot.patch
+++ b/patches/server/0561-Added-world-settings-for-mobs-picking-up-loot.patch
diff --git a/patches/server/0559-Implemented-BlockFailedDispenseEvent.patch b/patches/server/0562-Implemented-BlockFailedDispenseEvent.patch
index 9c14300d5a..9c14300d5a 100644
--- a/patches/server/0559-Implemented-BlockFailedDispenseEvent.patch
+++ b/patches/server/0562-Implemented-BlockFailedDispenseEvent.patch
diff --git a/patches/server/0560-Added-PlayerLecternPageChangeEvent.patch b/patches/server/0563-Added-PlayerLecternPageChangeEvent.patch
index d8fd03b1c7..d8fd03b1c7 100644
--- a/patches/server/0560-Added-PlayerLecternPageChangeEvent.patch
+++ b/patches/server/0563-Added-PlayerLecternPageChangeEvent.patch
diff --git a/patches/server/0561-Added-PlayerLoomPatternSelectEvent.patch b/patches/server/0564-Added-PlayerLoomPatternSelectEvent.patch
index a99d30af29..a99d30af29 100644
--- a/patches/server/0561-Added-PlayerLoomPatternSelectEvent.patch
+++ b/patches/server/0564-Added-PlayerLoomPatternSelectEvent.patch
diff --git a/patches/server/0562-Configurable-door-breaking-difficulty.patch b/patches/server/0565-Configurable-door-breaking-difficulty.patch
index 45e5e3e168..45e5e3e168 100644
--- a/patches/server/0562-Configurable-door-breaking-difficulty.patch
+++ b/patches/server/0565-Configurable-door-breaking-difficulty.patch
diff --git a/patches/server/0563-Empty-commands-shall-not-be-dispatched.patch b/patches/server/0566-Empty-commands-shall-not-be-dispatched.patch
index e2a473d34d..1c382dc0f6 100644
--- a/patches/server/0563-Empty-commands-shall-not-be-dispatched.patch
+++ b/patches/server/0566-Empty-commands-shall-not-be-dispatched.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] Empty commands shall not be dispatched
diff --git a/src/main/java/net/minecraft/commands/Commands.java b/src/main/java/net/minecraft/commands/Commands.java
-index 0efb172c31a211e03d5fd922f65b6feff1317381..52d2c8d451dce33a5a62f3ec3c5add65a80ce9ca 100644
+index b141d251eedd31bd115342b878afd68dc51a8518..6ad3fe4718a0db17ad6115753e533bf069ce57c6 100644
--- a/src/main/java/net/minecraft/commands/Commands.java
+++ b/src/main/java/net/minecraft/commands/Commands.java
@@ -245,6 +245,7 @@ public class Commands {
diff --git a/patches/server/0564-Implement-API-to-expose-exact-interaction-point.patch b/patches/server/0567-Implement-API-to-expose-exact-interaction-point.patch
index 0ede6bf153..0ede6bf153 100644
--- a/patches/server/0564-Implement-API-to-expose-exact-interaction-point.patch
+++ b/patches/server/0567-Implement-API-to-expose-exact-interaction-point.patch
diff --git a/patches/server/0565-Remove-stale-POIs.patch b/patches/server/0568-Remove-stale-POIs.patch
index 018ead4061..8627a969b7 100644
--- a/patches/server/0565-Remove-stale-POIs.patch
+++ b/patches/server/0568-Remove-stale-POIs.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Remove stale POIs
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index d78b75d00ff95eb0c9619420c2921881724d8561..3016947fb05211ffa72eef027db92d02e2486150 100644
+index 85c0a80f00f5968b684b3609fbe56197e4aeb202..3f4e3e57999245a83263e88e221723e72a11b31e 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
-@@ -1918,6 +1918,11 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -1920,6 +1920,11 @@ public class ServerLevel extends Level implements WorldGenLevel {
});
optional1.ifPresent((holder) -> {
this.getServer().execute(() -> {
diff --git a/patches/server/0566-Fix-villager-boat-exploit.patch b/patches/server/0569-Fix-villager-boat-exploit.patch
index 0ad7ee193e..293797f2f9 100644
--- a/patches/server/0566-Fix-villager-boat-exploit.patch
+++ b/patches/server/0569-Fix-villager-boat-exploit.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Fix villager boat exploit
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
-index 2fc183222e539e66c050e146c784a66222dee419..02611a3929d5cc0904e938db1314567ef23fb041 100644
+index 195fcf93c46967e14a3247768a575c7a73bf9e31..54fff5ebefa04f64ed1abfd12ebf48762015fae3 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
-@@ -635,6 +635,14 @@ public abstract class PlayerList {
+@@ -632,6 +632,14 @@ public abstract class PlayerList {
PlayerList.LOGGER.debug("Removing player mount");
entityplayer.stopRiding();
entity.getPassengersAndSelf().forEach((entity1) -> {
diff --git a/patches/server/0567-Add-sendOpLevel-API.patch b/patches/server/0570-Add-sendOpLevel-API.patch
index d418dc9362..67a367d475 100644
--- a/patches/server/0567-Add-sendOpLevel-API.patch
+++ b/patches/server/0570-Add-sendOpLevel-API.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Add sendOpLevel API
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
-index 02611a3929d5cc0904e938db1314567ef23fb041..5203bcb732c77b1c232ab262431914c53efd0ae9 100644
+index 54fff5ebefa04f64ed1abfd12ebf48762015fae3..c4f5a3bf60302743329b17f9b2dffcee9c1e5ab3 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
-@@ -1133,6 +1133,11 @@ public abstract class PlayerList {
+@@ -1130,6 +1130,11 @@ public abstract class PlayerList {
}
private void sendPlayerPermissionLevel(ServerPlayer player, int permissionLevel) {
@@ -20,7 +20,7 @@ index 02611a3929d5cc0904e938db1314567ef23fb041..5203bcb732c77b1c232ab262431914c5
if (player.connection != null) {
byte b0;
-@@ -1147,8 +1152,10 @@ public abstract class PlayerList {
+@@ -1144,8 +1149,10 @@ public abstract class PlayerList {
player.connection.send(new ClientboundEntityEventPacket(player, b0));
}
@@ -32,7 +32,7 @@ index 02611a3929d5cc0904e938db1314567ef23fb041..5203bcb732c77b1c232ab262431914c5
public boolean isWhiteListed(GameProfile profile) {
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
-index 99d6e2fcfb6605a712c48831a5b7bd22d123dee2..8608fbd5484498f0e478d857ea1dd548ad6a93e0 100644
+index 21f413b1e75c15fae888a4e6dccefbe822ad1c40..0528489348dc12c22bdb306a4b6c5c6a138f5347 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -606,6 +606,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
diff --git a/patches/server/0568-Add-PaperRegistry.patch b/patches/server/0571-Add-PaperRegistry.patch
index 613898a9f2..613898a9f2 100644
--- a/patches/server/0568-Add-PaperRegistry.patch
+++ b/patches/server/0571-Add-PaperRegistry.patch
diff --git a/patches/server/0569-Add-StructuresLocateEvent.patch b/patches/server/0572-Add-StructuresLocateEvent.patch
index c8d1241689..c8d1241689 100644
--- a/patches/server/0569-Add-StructuresLocateEvent.patch
+++ b/patches/server/0572-Add-StructuresLocateEvent.patch
diff --git a/patches/server/0570-Collision-option-for-requiring-a-player-participant.patch b/patches/server/0573-Collision-option-for-requiring-a-player-participant.patch
index 8859599601..8859599601 100644
--- a/patches/server/0570-Collision-option-for-requiring-a-player-participant.patch
+++ b/patches/server/0573-Collision-option-for-requiring-a-player-participant.patch
diff --git a/patches/server/0571-Remove-ProjectileHitEvent-call-when-fireballs-dead.patch b/patches/server/0574-Remove-ProjectileHitEvent-call-when-fireballs-dead.patch
index 1af8b9fb5e..1af8b9fb5e 100644
--- a/patches/server/0571-Remove-ProjectileHitEvent-call-when-fireballs-dead.patch
+++ b/patches/server/0574-Remove-ProjectileHitEvent-call-when-fireballs-dead.patch
diff --git a/patches/server/0572-Return-chat-component-with-empty-text-instead-of-thr.patch b/patches/server/0575-Return-chat-component-with-empty-text-instead-of-thr.patch
index b83b5915fd..b83b5915fd 100644
--- a/patches/server/0572-Return-chat-component-with-empty-text-instead-of-thr.patch
+++ b/patches/server/0575-Return-chat-component-with-empty-text-instead-of-thr.patch
diff --git a/patches/server/0573-Make-schedule-command-per-world.patch b/patches/server/0576-Make-schedule-command-per-world.patch
index 60f5d1fc66..60f5d1fc66 100644
--- a/patches/server/0573-Make-schedule-command-per-world.patch
+++ b/patches/server/0576-Make-schedule-command-per-world.patch
diff --git a/patches/server/0574-Configurable-max-leash-distance.patch b/patches/server/0577-Configurable-max-leash-distance.patch
index ba76f79b7f..ba76f79b7f 100644
--- a/patches/server/0574-Configurable-max-leash-distance.patch
+++ b/patches/server/0577-Configurable-max-leash-distance.patch
diff --git a/patches/server/0575-Implement-BlockPreDispenseEvent.patch b/patches/server/0578-Implement-BlockPreDispenseEvent.patch
index 34982b77cc..34982b77cc 100644
--- a/patches/server/0575-Implement-BlockPreDispenseEvent.patch
+++ b/patches/server/0578-Implement-BlockPreDispenseEvent.patch
diff --git a/patches/server/0576-Added-firing-of-PlayerChangeBeaconEffectEvent.patch b/patches/server/0579-Added-firing-of-PlayerChangeBeaconEffectEvent.patch
index 2f90dea41c..2f90dea41c 100644
--- a/patches/server/0576-Added-firing-of-PlayerChangeBeaconEffectEvent.patch
+++ b/patches/server/0579-Added-firing-of-PlayerChangeBeaconEffectEvent.patch
diff --git a/patches/server/0577-Add-toggle-for-always-placing-the-dragon-egg.patch b/patches/server/0580-Add-toggle-for-always-placing-the-dragon-egg.patch
index caffaecf90..caffaecf90 100644
--- a/patches/server/0577-Add-toggle-for-always-placing-the-dragon-egg.patch
+++ b/patches/server/0580-Add-toggle-for-always-placing-the-dragon-egg.patch
diff --git a/patches/server/0578-Added-PlayerStonecutterRecipeSelectEvent.patch b/patches/server/0581-Added-PlayerStonecutterRecipeSelectEvent.patch
index 1c6497d193..1c6497d193 100644
--- a/patches/server/0578-Added-PlayerStonecutterRecipeSelectEvent.patch
+++ b/patches/server/0581-Added-PlayerStonecutterRecipeSelectEvent.patch
diff --git a/patches/server/0579-Add-dropLeash-variable-to-EntityUnleashEvent.patch b/patches/server/0582-Add-dropLeash-variable-to-EntityUnleashEvent.patch
index 71ca7beca1..71ca7beca1 100644
--- a/patches/server/0579-Add-dropLeash-variable-to-EntityUnleashEvent.patch
+++ b/patches/server/0582-Add-dropLeash-variable-to-EntityUnleashEvent.patch
diff --git a/patches/server/0580-Reset-shield-blocking-on-dimension-change.patch b/patches/server/0583-Reset-shield-blocking-on-dimension-change.patch
index d418f0bca8..d418f0bca8 100644
--- a/patches/server/0580-Reset-shield-blocking-on-dimension-change.patch
+++ b/patches/server/0583-Reset-shield-blocking-on-dimension-change.patch
diff --git a/patches/server/0581-add-DragonEggFormEvent.patch b/patches/server/0584-add-DragonEggFormEvent.patch
index 40273bbb47..40273bbb47 100644
--- a/patches/server/0581-add-DragonEggFormEvent.patch
+++ b/patches/server/0584-add-DragonEggFormEvent.patch
diff --git a/patches/server/0582-EntityMoveEvent.patch b/patches/server/0585-EntityMoveEvent.patch
index c8d45b7990..739f60de98 100644
--- a/patches/server/0582-EntityMoveEvent.patch
+++ b/patches/server/0585-EntityMoveEvent.patch
@@ -17,7 +17,7 @@ index d60439d49de781b12af6fbe4ff89b7270f57cbeb..abd1935ebc12f963b563023eb5279ad1
this.profiler.push(() -> {
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index 3016947fb05211ffa72eef027db92d02e2486150..675c8f6d856c6fa333887fd4079504713f3e861e 100644
+index 3f4e3e57999245a83263e88e221723e72a11b31e..a1b0256c8faceae89e1eaf5e26c8b588085fa760 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -217,6 +217,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
diff --git a/patches/server/0583-added-option-to-disable-pathfinding-updates-on-block.patch b/patches/server/0586-added-option-to-disable-pathfinding-updates-on-block.patch
index 988e34627b..24045de2fb 100644
--- a/patches/server/0583-added-option-to-disable-pathfinding-updates-on-block.patch
+++ b/patches/server/0586-added-option-to-disable-pathfinding-updates-on-block.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] added option to disable pathfinding updates on block changes
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index 675c8f6d856c6fa333887fd4079504713f3e861e..221612cddc9dd839c96d03325ee243721f7f5a9c 100644
+index a1b0256c8faceae89e1eaf5e26c8b588085fa760..7f121ce977fd5779032450443c94634bc919009d 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
-@@ -1492,6 +1492,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -1494,6 +1494,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
}
this.getChunkSource().blockChanged(pos);
@@ -16,7 +16,7 @@ index 675c8f6d856c6fa333887fd4079504713f3e861e..221612cddc9dd839c96d03325ee24372
VoxelShape voxelshape = oldState.getCollisionShape(this, pos);
VoxelShape voxelshape1 = newState.getCollisionShape(this, pos);
-@@ -1533,6 +1534,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -1535,6 +1536,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
}
}
diff --git a/patches/server/0584-Inline-shift-direction-fields.patch b/patches/server/0587-Inline-shift-direction-fields.patch
index d4353368a2..d4353368a2 100644
--- a/patches/server/0584-Inline-shift-direction-fields.patch
+++ b/patches/server/0587-Inline-shift-direction-fields.patch
diff --git a/patches/server/0585-Allow-adding-items-to-BlockDropItemEvent.patch b/patches/server/0588-Allow-adding-items-to-BlockDropItemEvent.patch
index e71e9cff71..e71e9cff71 100644
--- a/patches/server/0585-Allow-adding-items-to-BlockDropItemEvent.patch
+++ b/patches/server/0588-Allow-adding-items-to-BlockDropItemEvent.patch
diff --git a/patches/server/0586-Add-getMainThreadExecutor-to-BukkitScheduler.patch b/patches/server/0589-Add-getMainThreadExecutor-to-BukkitScheduler.patch
index 8cfe3357dc..8cfe3357dc 100644
--- a/patches/server/0586-Add-getMainThreadExecutor-to-BukkitScheduler.patch
+++ b/patches/server/0589-Add-getMainThreadExecutor-to-BukkitScheduler.patch
diff --git a/patches/server/0587-living-entity-allow-attribute-registration.patch b/patches/server/0590-living-entity-allow-attribute-registration.patch
index 88cf7f15c6..88cf7f15c6 100644
--- a/patches/server/0587-living-entity-allow-attribute-registration.patch
+++ b/patches/server/0590-living-entity-allow-attribute-registration.patch
diff --git a/patches/server/0588-fix-dead-slime-setSize-invincibility.patch b/patches/server/0591-fix-dead-slime-setSize-invincibility.patch
index 33ce1b72f2..33ce1b72f2 100644
--- a/patches/server/0588-fix-dead-slime-setSize-invincibility.patch
+++ b/patches/server/0591-fix-dead-slime-setSize-invincibility.patch
diff --git a/patches/server/0589-Merchant-getRecipes-should-return-an-immutable-list.patch b/patches/server/0592-Merchant-getRecipes-should-return-an-immutable-list.patch
index cbb0cdc052..cbb0cdc052 100644
--- a/patches/server/0589-Merchant-getRecipes-should-return-an-immutable-list.patch
+++ b/patches/server/0592-Merchant-getRecipes-should-return-an-immutable-list.patch
diff --git a/patches/server/0590-Add-support-for-hex-color-codes-in-console.patch b/patches/server/0593-Add-support-for-hex-color-codes-in-console.patch
index 64b7398ff4..64b7398ff4 100644
--- a/patches/server/0590-Add-support-for-hex-color-codes-in-console.patch
+++ b/patches/server/0593-Add-support-for-hex-color-codes-in-console.patch
diff --git a/patches/server/0591-Expose-Tracked-Players.patch b/patches/server/0594-Expose-Tracked-Players.patch
index 116eacbb27..2a57f6e90d 100644
--- a/patches/server/0591-Expose-Tracked-Players.patch
+++ b/patches/server/0594-Expose-Tracked-Players.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] Expose Tracked Players
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
-index c39b683cbe83618daee0ca00d1107b115af6bf8f..b8e5205c165bcba5b8383334f3d0d1daf9d0a8cd 100644
+index fa1e996157fb3470c08669801e7482af70714b11..e9828bab16ac05babccfb1fefad85860c1a4768c 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
@@ -1282,5 +1282,18 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
diff --git a/patches/server/0592-Remove-streams-from-SensorNearest.patch b/patches/server/0595-Remove-streams-from-SensorNearest.patch
index a7ae5d1a98..a7ae5d1a98 100644
--- a/patches/server/0592-Remove-streams-from-SensorNearest.patch
+++ b/patches/server/0595-Remove-streams-from-SensorNearest.patch
diff --git a/patches/server/0593-Throw-proper-exception-on-empty-JsonList-file.patch b/patches/server/0596-Throw-proper-exception-on-empty-JsonList-file.patch
index e013e32526..e013e32526 100644
--- a/patches/server/0593-Throw-proper-exception-on-empty-JsonList-file.patch
+++ b/patches/server/0596-Throw-proper-exception-on-empty-JsonList-file.patch
diff --git a/patches/server/0594-Improve-ServerGUI.patch b/patches/server/0597-Improve-ServerGUI.patch
index e573bd2f58..e573bd2f58 100644
--- a/patches/server/0594-Improve-ServerGUI.patch
+++ b/patches/server/0597-Improve-ServerGUI.patch
diff --git a/patches/server/0595-stop-firing-pressure-plate-EntityInteractEvent-for-i.patch b/patches/server/0598-stop-firing-pressure-plate-EntityInteractEvent-for-i.patch
index 1099f41d55..1099f41d55 100644
--- a/patches/server/0595-stop-firing-pressure-plate-EntityInteractEvent-for-i.patch
+++ b/patches/server/0598-stop-firing-pressure-plate-EntityInteractEvent-for-i.patch
diff --git a/patches/server/0596-fix-converting-txt-to-json-file.patch b/patches/server/0599-fix-converting-txt-to-json-file.patch
index dfcc5eb724..a8f2f43419 100644
--- a/patches/server/0596-fix-converting-txt-to-json-file.patch
+++ b/patches/server/0599-fix-converting-txt-to-json-file.patch
@@ -48,7 +48,7 @@ index da83f111199a6b4c712a9bb8ab6f1d1b5c6ae77c..ef02ceba53943d34bd45070297c72bee
if (!OldUsersConverter.serverReadyAfterUserconversion(this)) {
return false;
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
-index 39ddb080e9a296fa499ea2959e22172500db6235..f7f0d7556d130197b8cb75841f1e326274eb59cd 100644
+index c4f5a3bf60302743329b17f9b2dffcee9c1e5ab3..a0b752e09f375fb72ff5ad7952b5ef6ebdb6c14b 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -177,6 +177,7 @@ public abstract class PlayerList {
diff --git a/patches/server/0597-Add-worldborder-events.patch b/patches/server/0600-Add-worldborder-events.patch
index af0cf2d370..af0cf2d370 100644
--- a/patches/server/0597-Add-worldborder-events.patch
+++ b/patches/server/0600-Add-worldborder-events.patch
diff --git a/patches/server/0598-added-PlayerNameEntityEvent.patch b/patches/server/0601-added-PlayerNameEntityEvent.patch
index c1df33b717..c1df33b717 100644
--- a/patches/server/0598-added-PlayerNameEntityEvent.patch
+++ b/patches/server/0601-added-PlayerNameEntityEvent.patch
diff --git a/patches/server/0599-Prevent-grindstones-from-overstacking-items.patch b/patches/server/0602-Prevent-grindstones-from-overstacking-items.patch
index 3e79faf014..3e79faf014 100644
--- a/patches/server/0599-Prevent-grindstones-from-overstacking-items.patch
+++ b/patches/server/0602-Prevent-grindstones-from-overstacking-items.patch
diff --git a/patches/server/0600-Add-recipe-to-cook-events.patch b/patches/server/0603-Add-recipe-to-cook-events.patch
index 61023ab91c..61023ab91c 100644
--- a/patches/server/0600-Add-recipe-to-cook-events.patch
+++ b/patches/server/0603-Add-recipe-to-cook-events.patch
diff --git a/patches/server/0601-Add-Block-isValidTool.patch b/patches/server/0604-Add-Block-isValidTool.patch
index 95bf6c3432..95bf6c3432 100644
--- a/patches/server/0601-Add-Block-isValidTool.patch
+++ b/patches/server/0604-Add-Block-isValidTool.patch
diff --git a/patches/server/0602-Allow-using-signs-inside-spawn-protection.patch b/patches/server/0605-Allow-using-signs-inside-spawn-protection.patch
index d48b61abd9..d48b61abd9 100644
--- a/patches/server/0602-Allow-using-signs-inside-spawn-protection.patch
+++ b/patches/server/0605-Allow-using-signs-inside-spawn-protection.patch
diff --git a/patches/server/0603-Expand-world-key-API.patch b/patches/server/0606-Expand-world-key-API.patch
index 3e4449fb6d..9d99a03dc8 100644
--- a/patches/server/0603-Expand-world-key-API.patch
+++ b/patches/server/0606-Expand-world-key-API.patch
@@ -20,7 +20,7 @@ index ee5e59c37301d9a806e2f696d52d9d217b232833..bb5d22125b6cd4e60d2b7e2e00af158c
// Paper end
}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-index f5ed17af815f2e7da523e80319dc4021556376b2..4a59e48f67a4ebd44562915ee866276c1270604b 100644
+index f5783a0df00c7c88c5d5d1c3b55ba671350cd0c6..cebc3c444681d6f422a8befff74476e7e0d8d22e 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -1143,9 +1143,15 @@ public final class CraftServer implements Server {
diff --git a/patches/server/0604-Add-fast-alternative-constructor-for-Rotations.patch b/patches/server/0607-Add-fast-alternative-constructor-for-Rotations.patch
index bbdcc665bb..bbdcc665bb 100644
--- a/patches/server/0604-Add-fast-alternative-constructor-for-Rotations.patch
+++ b/patches/server/0607-Add-fast-alternative-constructor-for-Rotations.patch
diff --git a/patches/server/0605-Item-Rarity-API.patch b/patches/server/0608-Item-Rarity-API.patch
index e3e4b42355..e3e4b42355 100644
--- a/patches/server/0605-Item-Rarity-API.patch
+++ b/patches/server/0608-Item-Rarity-API.patch
diff --git a/patches/server/0606-Only-set-despawnTimer-for-Wandering-Traders-spawned-.patch b/patches/server/0609-Only-set-despawnTimer-for-Wandering-Traders-spawned-.patch
index a8810d8bca..a8810d8bca 100644
--- a/patches/server/0606-Only-set-despawnTimer-for-Wandering-Traders-spawned-.patch
+++ b/patches/server/0609-Only-set-despawnTimer-for-Wandering-Traders-spawned-.patch
diff --git a/patches/server/0607-copy-TESign-isEditable-from-snapshots.patch b/patches/server/0610-copy-TESign-isEditable-from-snapshots.patch
index 766607080f..766607080f 100644
--- a/patches/server/0607-copy-TESign-isEditable-from-snapshots.patch
+++ b/patches/server/0610-copy-TESign-isEditable-from-snapshots.patch
diff --git a/patches/server/0608-Drop-carried-item-when-player-has-disconnected.patch b/patches/server/0611-Drop-carried-item-when-player-has-disconnected.patch
index 6235dc89f7..8d562472bc 100644
--- a/patches/server/0608-Drop-carried-item-when-player-has-disconnected.patch
+++ b/patches/server/0611-Drop-carried-item-when-player-has-disconnected.patch
@@ -7,10 +7,10 @@ Fixes disappearance of held items, when a player gets disconnected and PlayerDro
Closes #5036
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
-index 57e1fa9aa74b237763eb797a4fbe67b791666f84..b4a4fe2ba4cb00ed25fe5899723623f8e915d8d6 100644
+index a0b752e09f375fb72ff5ad7952b5ef6ebdb6c14b..8eae2de23226700b7186b5e673f7f776854a49bc 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
-@@ -628,6 +628,14 @@ public abstract class PlayerList {
+@@ -625,6 +625,14 @@ public abstract class PlayerList {
}
// Paper end
diff --git a/patches/server/0609-forced-whitelist-use-configurable-kick-message.patch b/patches/server/0612-forced-whitelist-use-configurable-kick-message.patch
index 3066195a02..3066195a02 100644
--- a/patches/server/0609-forced-whitelist-use-configurable-kick-message.patch
+++ b/patches/server/0612-forced-whitelist-use-configurable-kick-message.patch
diff --git a/patches/server/0610-Don-t-ignore-result-of-PlayerEditBookEvent.patch b/patches/server/0613-Don-t-ignore-result-of-PlayerEditBookEvent.patch
index 8fc5df118e..8fc5df118e 100644
--- a/patches/server/0610-Don-t-ignore-result-of-PlayerEditBookEvent.patch
+++ b/patches/server/0613-Don-t-ignore-result-of-PlayerEditBookEvent.patch
diff --git a/patches/server/0611-Entity-load-save-limit-per-chunk.patch b/patches/server/0614-Entity-load-save-limit-per-chunk.patch
index 64d4f515d8..64d4f515d8 100644
--- a/patches/server/0611-Entity-load-save-limit-per-chunk.patch
+++ b/patches/server/0614-Entity-load-save-limit-per-chunk.patch
diff --git a/patches/server/0612-Expose-protocol-version.patch b/patches/server/0615-Expose-protocol-version.patch
index d01a192416..d01a192416 100644
--- a/patches/server/0612-Expose-protocol-version.patch
+++ b/patches/server/0615-Expose-protocol-version.patch
diff --git a/patches/server/0613-Enhance-console-tab-completions-for-brigadier-comman.patch b/patches/server/0616-Enhance-console-tab-completions-for-brigadier-comman.patch
index a40851fee2..a40851fee2 100644
--- a/patches/server/0613-Enhance-console-tab-completions-for-brigadier-comman.patch
+++ b/patches/server/0616-Enhance-console-tab-completions-for-brigadier-comman.patch
diff --git a/patches/server/0614-Fix-PlayerItemConsumeEvent-cancelling-properly.patch b/patches/server/0617-Fix-PlayerItemConsumeEvent-cancelling-properly.patch
index 6079bd7fd6..6079bd7fd6 100644
--- a/patches/server/0614-Fix-PlayerItemConsumeEvent-cancelling-properly.patch
+++ b/patches/server/0617-Fix-PlayerItemConsumeEvent-cancelling-properly.patch
diff --git a/patches/server/0615-Add-bypass-host-check.patch b/patches/server/0618-Add-bypass-host-check.patch
index 85854dc71d..85854dc71d 100644
--- a/patches/server/0615-Add-bypass-host-check.patch
+++ b/patches/server/0618-Add-bypass-host-check.patch
diff --git a/patches/server/0616-Set-area-affect-cloud-rotation.patch b/patches/server/0619-Set-area-affect-cloud-rotation.patch
index 08e992b45c..08e992b45c 100644
--- a/patches/server/0616-Set-area-affect-cloud-rotation.patch
+++ b/patches/server/0619-Set-area-affect-cloud-rotation.patch
diff --git a/patches/server/0617-add-isDeeplySleeping-to-HumanEntity.patch b/patches/server/0620-add-isDeeplySleeping-to-HumanEntity.patch
index 18ba539fd0..18ba539fd0 100644
--- a/patches/server/0617-add-isDeeplySleeping-to-HumanEntity.patch
+++ b/patches/server/0620-add-isDeeplySleeping-to-HumanEntity.patch
diff --git a/patches/server/0618-add-consumeFuel-to-FurnaceBurnEvent.patch b/patches/server/0621-add-consumeFuel-to-FurnaceBurnEvent.patch
index 0c37516dd7..0c37516dd7 100644
--- a/patches/server/0618-add-consumeFuel-to-FurnaceBurnEvent.patch
+++ b/patches/server/0621-add-consumeFuel-to-FurnaceBurnEvent.patch
diff --git a/patches/server/0619-add-get-set-drop-chance-to-EntityEquipment.patch b/patches/server/0622-add-get-set-drop-chance-to-EntityEquipment.patch
index 9720fcdaf4..9720fcdaf4 100644
--- a/patches/server/0619-add-get-set-drop-chance-to-EntityEquipment.patch
+++ b/patches/server/0622-add-get-set-drop-chance-to-EntityEquipment.patch
diff --git a/patches/server/0620-fix-PigZombieAngerEvent-cancellation.patch b/patches/server/0623-fix-PigZombieAngerEvent-cancellation.patch
index df4e7b0b17..df4e7b0b17 100644
--- a/patches/server/0620-fix-PigZombieAngerEvent-cancellation.patch
+++ b/patches/server/0623-fix-PigZombieAngerEvent-cancellation.patch
diff --git a/patches/server/0621-Fix-checkReach-check-for-Shulker-boxes.patch b/patches/server/0624-Fix-checkReach-check-for-Shulker-boxes.patch
index e63651a68f..e63651a68f 100644
--- a/patches/server/0621-Fix-checkReach-check-for-Shulker-boxes.patch
+++ b/patches/server/0624-Fix-checkReach-check-for-Shulker-boxes.patch
diff --git a/patches/server/0622-fix-PlayerItemHeldEvent-firing-twice.patch b/patches/server/0625-fix-PlayerItemHeldEvent-firing-twice.patch
index ad85704974..ad85704974 100644
--- a/patches/server/0622-fix-PlayerItemHeldEvent-firing-twice.patch
+++ b/patches/server/0625-fix-PlayerItemHeldEvent-firing-twice.patch
diff --git a/patches/server/0623-Added-PlayerDeepSleepEvent.patch b/patches/server/0626-Added-PlayerDeepSleepEvent.patch
index b7989ecad1..b7989ecad1 100644
--- a/patches/server/0623-Added-PlayerDeepSleepEvent.patch
+++ b/patches/server/0626-Added-PlayerDeepSleepEvent.patch
diff --git a/patches/server/0624-More-World-API.patch b/patches/server/0627-More-World-API.patch
index d6a3687642..fb9c49f999 100644
--- a/patches/server/0624-More-World-API.patch
+++ b/patches/server/0627-More-World-API.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] More World API
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-index da84c3106b9e6210e234585fdd9eb75e1db041f5..4e552504b207a91b9fbd7f2a7f6e96e1fe81cfe2 100644
+index 42423b020f9c2ef2ba025b444be076c38314c721..9ca188959484041f53a078963cb79d68fd2a4f48 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-@@ -2046,6 +2046,65 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+@@ -2045,6 +2045,65 @@ public class CraftWorld extends CraftRegionAccessor implements World {
return new CraftStructureSearchResult(CraftStructure.minecraftToBukkit(found.getSecond().value(), this.getHandle().registryAccess()), new Location(this, found.getFirst().getX(), found.getFirst().getY(), found.getFirst().getZ()));
}
diff --git a/patches/server/0625-Added-PlayerBedFailEnterEvent.patch b/patches/server/0628-Added-PlayerBedFailEnterEvent.patch
index ad6eaeb223..ad6eaeb223 100644
--- a/patches/server/0625-Added-PlayerBedFailEnterEvent.patch
+++ b/patches/server/0628-Added-PlayerBedFailEnterEvent.patch
diff --git a/patches/server/0626-Implement-methods-to-convert-between-Component-and-B.patch b/patches/server/0629-Implement-methods-to-convert-between-Component-and-B.patch
index 3e1d661a26..3e1d661a26 100644
--- a/patches/server/0626-Implement-methods-to-convert-between-Component-and-B.patch
+++ b/patches/server/0629-Implement-methods-to-convert-between-Component-and-B.patch
diff --git a/patches/server/0627-Fix-anchor-respawn-acting-as-a-bed-respawn-from-the-.patch b/patches/server/0630-Fix-anchor-respawn-acting-as-a-bed-respawn-from-the-.patch
index cfe54e00f8..e51b27c728 100644
--- a/patches/server/0627-Fix-anchor-respawn-acting-as-a-bed-respawn-from-the-.patch
+++ b/patches/server/0630-Fix-anchor-respawn-acting-as-a-bed-respawn-from-the-.patch
@@ -6,10 +6,10 @@ Subject: [PATCH] Fix anchor respawn acting as a bed respawn from the end
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
-index b4a4fe2ba4cb00ed25fe5899723623f8e915d8d6..b41b9d9ac1e28f44eed4b6c56d63cb5f249b9ea7 100644
+index 8eae2de23226700b7186b5e673f7f776854a49bc..6bdcfe46fd447cfdf2e57bb60250984f02c195da 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
-@@ -861,6 +861,7 @@ public abstract class PlayerList {
+@@ -858,6 +858,7 @@ public abstract class PlayerList {
// Paper start
boolean isBedSpawn = false;
@@ -17,7 +17,7 @@ index b4a4fe2ba4cb00ed25fe5899723623f8e915d8d6..b41b9d9ac1e28f44eed4b6c56d63cb5f
boolean isRespawn = false;
boolean isLocAltered = false; // Paper - Fix SPIGOT-5989
// Paper end
-@@ -881,6 +882,7 @@ public abstract class PlayerList {
+@@ -878,6 +879,7 @@ public abstract class PlayerList {
if (optional.isPresent()) {
BlockState iblockdata = worldserver1.getBlockState(blockposition);
boolean flag3 = iblockdata.is(Blocks.RESPAWN_ANCHOR);
@@ -25,7 +25,7 @@ index b4a4fe2ba4cb00ed25fe5899723623f8e915d8d6..b41b9d9ac1e28f44eed4b6c56d63cb5f
Vec3 vec3d = (Vec3) optional.get();
float f1;
-@@ -909,7 +911,7 @@ public abstract class PlayerList {
+@@ -906,7 +908,7 @@ public abstract class PlayerList {
}
Player respawnPlayer = entityplayer1.getBukkitEntity();
diff --git a/patches/server/0628-Introduce-beacon-activation-deactivation-events.patch b/patches/server/0631-Introduce-beacon-activation-deactivation-events.patch
index b3f265d709..b3f265d709 100644
--- a/patches/server/0628-Introduce-beacon-activation-deactivation-events.patch
+++ b/patches/server/0631-Introduce-beacon-activation-deactivation-events.patch
diff --git a/patches/server/0629-add-RespawnFlags-to-PlayerRespawnEvent.patch b/patches/server/0632-add-RespawnFlags-to-PlayerRespawnEvent.patch
index 19655c9810..de0eea12c9 100644
--- a/patches/server/0629-add-RespawnFlags-to-PlayerRespawnEvent.patch
+++ b/patches/server/0632-add-RespawnFlags-to-PlayerRespawnEvent.patch
@@ -18,10 +18,10 @@ index 35b906d74a4cc03a5878cedff2ee9e694bb03ad4..1a987fe9bbfe4e59e6a10a0ef94e1b18
} else {
if (this.player.getHealth() > 0.0F) {
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
-index b41b9d9ac1e28f44eed4b6c56d63cb5f249b9ea7..4b00359d413058c49f79db8cdd81eaa1e729e3a7 100644
+index 6bdcfe46fd447cfdf2e57bb60250984f02c195da..977a23684b061d7390f70f8754a1d879d7d7075a 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
-@@ -820,6 +820,12 @@ public abstract class PlayerList {
+@@ -817,6 +817,12 @@ public abstract class PlayerList {
}
public ServerPlayer respawn(ServerPlayer entityplayer, ServerLevel worldserver, boolean flag, Location location, boolean avoidSuffocation) {
@@ -34,7 +34,7 @@ index b41b9d9ac1e28f44eed4b6c56d63cb5f249b9ea7..4b00359d413058c49f79db8cdd81eaa1
entityplayer.stopRiding(); // CraftBukkit
this.players.remove(entityplayer);
this.playersByName.remove(entityplayer.getScoreboardName().toLowerCase(java.util.Locale.ROOT)); // Spigot
-@@ -911,7 +917,7 @@ public abstract class PlayerList {
+@@ -908,7 +914,7 @@ public abstract class PlayerList {
}
Player respawnPlayer = entityplayer1.getBukkitEntity();
diff --git a/patches/server/0630-Add-Channel-initialization-listeners.patch b/patches/server/0633-Add-Channel-initialization-listeners.patch
index fbea93e057..fbea93e057 100644
--- a/patches/server/0630-Add-Channel-initialization-listeners.patch
+++ b/patches/server/0633-Add-Channel-initialization-listeners.patch
diff --git a/patches/server/0631-Send-empty-commands-if-tab-completion-is-disabled.patch b/patches/server/0634-Send-empty-commands-if-tab-completion-is-disabled.patch
index c8fb05fbfb..e31efa98f9 100644
--- a/patches/server/0631-Send-empty-commands-if-tab-completion-is-disabled.patch
+++ b/patches/server/0634-Send-empty-commands-if-tab-completion-is-disabled.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] Send empty commands if tab completion is disabled
diff --git a/src/main/java/net/minecraft/commands/Commands.java b/src/main/java/net/minecraft/commands/Commands.java
-index 52d2c8d451dce33a5a62f3ec3c5add65a80ce9ca..884a7c3a082140d2e1d154851c534ab09f5da4ce 100644
+index 6ad3fe4718a0db17ad6115753e533bf069ce57c6..9c0b2679964f864671ff4041163d1065c8d9cf84 100644
--- a/src/main/java/net/minecraft/commands/Commands.java
+++ b/src/main/java/net/minecraft/commands/Commands.java
@@ -358,7 +358,12 @@ public class Commands {
diff --git a/patches/server/0632-Add-more-WanderingTrader-API.patch b/patches/server/0635-Add-more-WanderingTrader-API.patch
index 65d351d6df..65d351d6df 100644
--- a/patches/server/0632-Add-more-WanderingTrader-API.patch
+++ b/patches/server/0635-Add-more-WanderingTrader-API.patch
diff --git a/patches/server/0633-Add-EntityBlockStorage-clearEntities.patch b/patches/server/0636-Add-EntityBlockStorage-clearEntities.patch
index 2bd0ddfa38..2bd0ddfa38 100644
--- a/patches/server/0633-Add-EntityBlockStorage-clearEntities.patch
+++ b/patches/server/0636-Add-EntityBlockStorage-clearEntities.patch
diff --git a/patches/server/0634-Add-Adventure-message-to-PlayerAdvancementDoneEvent.patch b/patches/server/0637-Add-Adventure-message-to-PlayerAdvancementDoneEvent.patch
index 4169ad0754..4169ad0754 100644
--- a/patches/server/0634-Add-Adventure-message-to-PlayerAdvancementDoneEvent.patch
+++ b/patches/server/0637-Add-Adventure-message-to-PlayerAdvancementDoneEvent.patch
diff --git a/patches/server/0635-Add-raw-address-to-AsyncPlayerPreLoginEvent.patch b/patches/server/0638-Add-raw-address-to-AsyncPlayerPreLoginEvent.patch
index 8402d0763d..8402d0763d 100644
--- a/patches/server/0635-Add-raw-address-to-AsyncPlayerPreLoginEvent.patch
+++ b/patches/server/0638-Add-raw-address-to-AsyncPlayerPreLoginEvent.patch
diff --git a/patches/server/0636-Inventory-close.patch b/patches/server/0639-Inventory-close.patch
index e7f478324a..e7f478324a 100644
--- a/patches/server/0636-Inventory-close.patch
+++ b/patches/server/0639-Inventory-close.patch
diff --git a/patches/server/0637-call-PortalCreateEvent-players-and-end-platform.patch b/patches/server/0640-call-PortalCreateEvent-players-and-end-platform.patch
index 11bc717f06..11bc717f06 100644
--- a/patches/server/0637-call-PortalCreateEvent-players-and-end-platform.patch
+++ b/patches/server/0640-call-PortalCreateEvent-players-and-end-platform.patch
diff --git a/patches/server/0638-Add-a-should-burn-in-sunlight-API-for-Phantoms-and-S.patch b/patches/server/0641-Add-a-should-burn-in-sunlight-API-for-Phantoms-and-S.patch
index 15c8339c99..15c8339c99 100644
--- a/patches/server/0638-Add-a-should-burn-in-sunlight-API-for-Phantoms-and-S.patch
+++ b/patches/server/0641-Add-a-should-burn-in-sunlight-API-for-Phantoms-and-S.patch
diff --git a/patches/server/0639-Fix-CraftPotionBrewer-cache.patch b/patches/server/0642-Fix-CraftPotionBrewer-cache.patch
index 2d8295382f..2d8295382f 100644
--- a/patches/server/0639-Fix-CraftPotionBrewer-cache.patch
+++ b/patches/server/0642-Fix-CraftPotionBrewer-cache.patch
diff --git a/patches/server/0640-Add-basic-Datapack-API.patch b/patches/server/0643-Add-basic-Datapack-API.patch
index 07268ceca0..1c6af9a618 100644
--- a/patches/server/0640-Add-basic-Datapack-API.patch
+++ b/patches/server/0643-Add-basic-Datapack-API.patch
@@ -92,7 +92,7 @@ index 0000000000000000000000000000000000000000..cf4374493c11057451a62a655514415c
+ }
+}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-index 4a59e48f67a4ebd44562915ee866276c1270604b..7490d6cd392defa93d64fd20cd47caf9b62ddd9b 100644
+index cebc3c444681d6f422a8befff74476e7e0d8d22e..9447b7cf08401608b2b79e8c68f58fd977cf0d42 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -282,6 +282,7 @@ public final class CraftServer implements Server {
diff --git a/patches/server/0641-Add-environment-variable-to-disable-server-gui.patch b/patches/server/0644-Add-environment-variable-to-disable-server-gui.patch
index 426508e900..426508e900 100644
--- a/patches/server/0641-Add-environment-variable-to-disable-server-gui.patch
+++ b/patches/server/0644-Add-environment-variable-to-disable-server-gui.patch
diff --git a/patches/server/0642-additions-to-PlayerGameModeChangeEvent.patch b/patches/server/0645-additions-to-PlayerGameModeChangeEvent.patch
index 1236b864d5..51ec4454fc 100644
--- a/patches/server/0642-additions-to-PlayerGameModeChangeEvent.patch
+++ b/patches/server/0645-additions-to-PlayerGameModeChangeEvent.patch
@@ -139,10 +139,10 @@ index 1a987fe9bbfe4e59e6a10a0ef94e1b18ed874a9a..66d5b3d44fb56aa6142f730e4742bb8f
}
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
-index 8608fbd5484498f0e478d857ea1dd548ad6a93e0..0004b78b63a2bf4b34467f9a550f6f0807e4dfb4 100644
+index 0528489348dc12c22bdb306a4b6c5c6a138f5347..ca8267966307ed5e0cb2fc5e4cf61868a77f50ed 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
-@@ -1396,7 +1396,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
+@@ -1386,7 +1386,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
throw new IllegalArgumentException("Mode cannot be null");
}
diff --git a/patches/server/0643-ItemStack-repair-check-API.patch b/patches/server/0646-ItemStack-repair-check-API.patch
index 136bbcb302..136bbcb302 100644
--- a/patches/server/0643-ItemStack-repair-check-API.patch
+++ b/patches/server/0646-ItemStack-repair-check-API.patch
diff --git a/patches/server/0644-More-Enchantment-API.patch b/patches/server/0647-More-Enchantment-API.patch
index 9068048df0..9068048df0 100644
--- a/patches/server/0644-More-Enchantment-API.patch
+++ b/patches/server/0647-More-Enchantment-API.patch
diff --git a/patches/server/0645-Move-range-check-for-block-placing-up.patch b/patches/server/0648-Move-range-check-for-block-placing-up.patch
index bb8c5f2bad..bb8c5f2bad 100644
--- a/patches/server/0645-Move-range-check-for-block-placing-up.patch
+++ b/patches/server/0648-Move-range-check-for-block-placing-up.patch
diff --git a/patches/server/0646-Fix-and-optimise-world-force-upgrading.patch b/patches/server/0649-Fix-and-optimise-world-force-upgrading.patch
index cb25250fdc..3ee5093552 100644
--- a/patches/server/0646-Fix-and-optimise-world-force-upgrading.patch
+++ b/patches/server/0649-Fix-and-optimise-world-force-upgrading.patch
@@ -272,7 +272,7 @@ index ce4aed84d751a48dcd2a8409190db4a22d78f77b..0a843e0afbcb1af8e2641515eb244b79
Main.LOGGER.info("Forcing world upgrade! {}", session.getLevelId()); // CraftBukkit
WorldUpgrader worldupgrader = new WorldUpgrader(session, dataFixer, generatorOptions, eraseCache);
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
-index 486acce909cdd2cacc5f2bb9eab1a600152f9971..749421b638bbb5868a426888e42edc461ad0edf3 100644
+index 3c5b7f4b2db421d56e5832e283bd60702b2d67de..84e76fbe3eca77b112c9dff936e21cba1c83e5aa 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -545,11 +545,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -323,7 +323,7 @@ index d9a88b29cfefcdbce7bfc477b6c1af0e51079102..c21274a72dca31c9160ecbcfa7eb42de
return this.world;
}
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
-index a96a6af2bcec3134b7caa32299bd07af50e83b89..0d96d1c0b66c57c680759f3567ef1b0c326d8cfa 100644
+index 2a6a4a62feb1c02bef850b0cda578f6f9d46a5e3..666286f94f09299f95538ef2f19b588eb74d9dda 100644
--- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
@@ -32,6 +32,28 @@ public class RegionFileStorage implements AutoCloseable {
@@ -356,7 +356,7 @@ index a96a6af2bcec3134b7caa32299bd07af50e83b89..0d96d1c0b66c57c680759f3567ef1b0c
return this.regionCache.getAndMoveToFirst(ChunkPos.asLong(chunkcoordintpair.getRegionX(), chunkcoordintpair.getRegionZ()));
}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-index 7490d6cd392defa93d64fd20cd47caf9b62ddd9b..96e207db7c06f02bdcae9af482bf2d36b5baee9b 100644
+index 9447b7cf08401608b2b79e8c68f58fd977cf0d42..dd43414dde55a5b447f9f51e4e5eef12fbbcfbde 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -1204,12 +1204,7 @@ public final class CraftServer implements Server {
diff --git a/patches/server/0647-Add-Mob-lookAt-API.patch b/patches/server/0650-Add-Mob-lookAt-API.patch
index 14378270ee..14378270ee 100644
--- a/patches/server/0647-Add-Mob-lookAt-API.patch
+++ b/patches/server/0650-Add-Mob-lookAt-API.patch
diff --git a/patches/server/0648-Add-Unix-domain-socket-support.patch b/patches/server/0651-Add-Unix-domain-socket-support.patch
index 7873f07d98..7873f07d98 100644
--- a/patches/server/0648-Add-Unix-domain-socket-support.patch
+++ b/patches/server/0651-Add-Unix-domain-socket-support.patch
diff --git a/patches/server/0649-Add-EntityInsideBlockEvent.patch b/patches/server/0652-Add-EntityInsideBlockEvent.patch
index 0ca02bfa9a..0ca02bfa9a 100644
--- a/patches/server/0649-Add-EntityInsideBlockEvent.patch
+++ b/patches/server/0652-Add-EntityInsideBlockEvent.patch
diff --git a/patches/server/0650-Attributes-API-for-item-defaults.patch b/patches/server/0653-Attributes-API-for-item-defaults.patch
index 882921f7c0..882921f7c0 100644
--- a/patches/server/0650-Attributes-API-for-item-defaults.patch
+++ b/patches/server/0653-Attributes-API-for-item-defaults.patch
diff --git a/patches/server/0651-Add-cause-to-Weather-ThunderChangeEvents.patch b/patches/server/0654-Add-cause-to-Weather-ThunderChangeEvents.patch
index 4b29a7dc83..ebde715e98 100644
--- a/patches/server/0651-Add-cause-to-Weather-ThunderChangeEvents.patch
+++ b/patches/server/0654-Add-cause-to-Weather-ThunderChangeEvents.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Add cause to Weather/ThunderChangeEvents
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index 221612cddc9dd839c96d03325ee243721f7f5a9c..cfdf7d844390310f792cee93d6a149aa65bb7055 100644
+index 7f121ce977fd5779032450443c94634bc919009d..6e9f1f01227a94480043ba3120c77f1ae080ec02 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
-@@ -496,8 +496,8 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -498,8 +498,8 @@ public class ServerLevel extends Level implements WorldGenLevel {
this.serverLevelData.setClearWeatherTime(clearDuration);
this.serverLevelData.setRainTime(rainDuration);
this.serverLevelData.setThunderTime(rainDuration);
@@ -19,7 +19,7 @@ index 221612cddc9dd839c96d03325ee243721f7f5a9c..cfdf7d844390310f792cee93d6a149aa
}
@Override
-@@ -889,8 +889,8 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -891,8 +891,8 @@ public class ServerLevel extends Level implements WorldGenLevel {
this.serverLevelData.setThunderTime(j);
this.serverLevelData.setRainTime(k);
this.serverLevelData.setClearWeatherTime(i);
@@ -30,7 +30,7 @@ index 221612cddc9dd839c96d03325ee243721f7f5a9c..cfdf7d844390310f792cee93d6a149aa
}
this.oThunderLevel = this.thunderLevel;
-@@ -956,14 +956,14 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -958,14 +958,14 @@ public class ServerLevel extends Level implements WorldGenLevel {
private void resetWeatherCycle() {
// CraftBukkit start
@@ -95,10 +95,10 @@ index 401787a5b55384b9ab7755e822b3b881dc45ac45..e537a8df45c31efa80cb898cbef9c3a0
if (weather.isCancelled()) {
return;
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-index 4e552504b207a91b9fbd7f2a7f6e96e1fe81cfe2..85972e19324027beaf215bed1b45947f976f5db4 100644
+index 9ca188959484041f53a078963cb79d68fd2a4f48..5fbc8fabf1c94798c21035049f6585e915da0536 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-@@ -1195,7 +1195,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+@@ -1194,7 +1194,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@Override
public void setStorm(boolean hasStorm) {
@@ -107,7 +107,7 @@ index 4e552504b207a91b9fbd7f2a7f6e96e1fe81cfe2..85972e19324027beaf215bed1b45947f
this.setWeatherDuration(0); // Reset weather duration (legacy behaviour)
this.setClearWeatherDuration(0); // Reset clear weather duration (reset "/weather clear" commands)
}
-@@ -1217,7 +1217,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+@@ -1216,7 +1216,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@Override
public void setThundering(boolean thundering) {
diff --git a/patches/server/0652-More-Lidded-Block-API.patch b/patches/server/0655-More-Lidded-Block-API.patch
index 135fd68698..135fd68698 100644
--- a/patches/server/0652-More-Lidded-Block-API.patch
+++ b/patches/server/0655-More-Lidded-Block-API.patch
diff --git a/patches/server/0653-Limit-item-frame-cursors-on-maps.patch b/patches/server/0656-Limit-item-frame-cursors-on-maps.patch
index 4e2cd3bfa2..4e2cd3bfa2 100644
--- a/patches/server/0653-Limit-item-frame-cursors-on-maps.patch
+++ b/patches/server/0656-Limit-item-frame-cursors-on-maps.patch
diff --git a/patches/server/0654-Add-PlayerKickEvent-causes.patch b/patches/server/0657-Add-PlayerKickEvent-causes.patch
index cfd6959de4..b1df3653af 100644
--- a/patches/server/0654-Add-PlayerKickEvent-causes.patch
+++ b/patches/server/0657-Add-PlayerKickEvent-causes.patch
@@ -367,10 +367,10 @@ index da9001a29b2ec2f715336c8187e6c918dd32db5e..b87d5dda2ac847cdc4c83b713568d9e9
}
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
-index 4b00359d413058c49f79db8cdd81eaa1e729e3a7..07423d228b91d1482498c2e22bc23bf3ae997a38 100644
+index 977a23684b061d7390f70f8754a1d879d7d7075a..cd7fdf629ac1dd17e83445afdf352c33823cbd25 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
-@@ -729,7 +729,7 @@ public abstract class PlayerList {
+@@ -726,7 +726,7 @@ public abstract class PlayerList {
while (iterator.hasNext()) {
entityplayer = (ServerPlayer) iterator.next();
this.save(entityplayer); // CraftBukkit - Force the player's inventory to be saved
@@ -379,7 +379,7 @@ index 4b00359d413058c49f79db8cdd81eaa1e729e3a7..07423d228b91d1482498c2e22bc23bf3
}
// Instead of kicking then returning, we need to store the kick reason
-@@ -1360,8 +1360,8 @@ public abstract class PlayerList {
+@@ -1357,8 +1357,8 @@ public abstract class PlayerList {
// Paper end
// CraftBukkit start - disconnect safely
for (ServerPlayer player : this.players) {
@@ -391,7 +391,7 @@ index 4b00359d413058c49f79db8cdd81eaa1e729e3a7..07423d228b91d1482498c2e22bc23bf3
// CraftBukkit end
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
-index 0004b78b63a2bf4b34467f9a550f6f0807e4dfb4..4750ac09f2abfb712b042028a95d23121ffc049f 100644
+index ca8267966307ed5e0cb2fc5e4cf61868a77f50ed..a7a0b892b50302ac7af4588bb65206834134dba2 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -516,7 +516,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
diff --git a/patches/server/0655-Add-PufferFishStateChangeEvent.patch b/patches/server/0658-Add-PufferFishStateChangeEvent.patch
index e15126884a..e15126884a 100644
--- a/patches/server/0655-Add-PufferFishStateChangeEvent.patch
+++ b/patches/server/0658-Add-PufferFishStateChangeEvent.patch
diff --git a/patches/server/0656-Fix-PlayerBucketEmptyEvent-result-itemstack.patch b/patches/server/0659-Fix-PlayerBucketEmptyEvent-result-itemstack.patch
index 0ebe5f6ad9..0ebe5f6ad9 100644
--- a/patches/server/0656-Fix-PlayerBucketEmptyEvent-result-itemstack.patch
+++ b/patches/server/0659-Fix-PlayerBucketEmptyEvent-result-itemstack.patch
diff --git a/patches/server/0657-Synchronize-PalettedContainer-instead-of-ThreadingDe.patch b/patches/server/0660-Synchronize-PalettedContainer-instead-of-ThreadingDe.patch
index af97198c95..af97198c95 100644
--- a/patches/server/0657-Synchronize-PalettedContainer-instead-of-ThreadingDe.patch
+++ b/patches/server/0660-Synchronize-PalettedContainer-instead-of-ThreadingDe.patch
diff --git a/patches/server/0658-Add-option-to-fix-items-merging-through-walls.patch b/patches/server/0661-Add-option-to-fix-items-merging-through-walls.patch
index 0c6f1b92fc..0c6f1b92fc 100644
--- a/patches/server/0658-Add-option-to-fix-items-merging-through-walls.patch
+++ b/patches/server/0661-Add-option-to-fix-items-merging-through-walls.patch
diff --git a/patches/server/0659-Add-BellRevealRaiderEvent.patch b/patches/server/0662-Add-BellRevealRaiderEvent.patch
index 587e0f0400..587e0f0400 100644
--- a/patches/server/0659-Add-BellRevealRaiderEvent.patch
+++ b/patches/server/0662-Add-BellRevealRaiderEvent.patch
diff --git a/patches/server/0660-Fix-invulnerable-end-crystals.patch b/patches/server/0663-Fix-invulnerable-end-crystals.patch
index e5ce326afa..e5ce326afa 100644
--- a/patches/server/0660-Fix-invulnerable-end-crystals.patch
+++ b/patches/server/0663-Fix-invulnerable-end-crystals.patch
diff --git a/patches/server/0661-Add-ElderGuardianAppearanceEvent.patch b/patches/server/0664-Add-ElderGuardianAppearanceEvent.patch
index 13c35cf8b6..13c35cf8b6 100644
--- a/patches/server/0661-Add-ElderGuardianAppearanceEvent.patch
+++ b/patches/server/0664-Add-ElderGuardianAppearanceEvent.patch
diff --git a/patches/server/0662-Fix-dangerous-end-portal-logic.patch b/patches/server/0665-Fix-dangerous-end-portal-logic.patch
index f8757be01f..f8757be01f 100644
--- a/patches/server/0662-Fix-dangerous-end-portal-logic.patch
+++ b/patches/server/0665-Fix-dangerous-end-portal-logic.patch
diff --git a/patches/server/0663-Optimize-Biome-Mob-Lookups-for-Mob-Spawning.patch b/patches/server/0666-Optimize-Biome-Mob-Lookups-for-Mob-Spawning.patch
index c46f8fbb65..c46f8fbb65 100644
--- a/patches/server/0663-Optimize-Biome-Mob-Lookups-for-Mob-Spawning.patch
+++ b/patches/server/0666-Optimize-Biome-Mob-Lookups-for-Mob-Spawning.patch
diff --git a/patches/server/0664-Make-item-validations-configurable.patch b/patches/server/0667-Make-item-validations-configurable.patch
index 8c87e474af..8c87e474af 100644
--- a/patches/server/0664-Make-item-validations-configurable.patch
+++ b/patches/server/0667-Make-item-validations-configurable.patch
diff --git a/patches/server/0665-Line-Of-Sight-Changes.patch b/patches/server/0668-Line-Of-Sight-Changes.patch
index 23a60d3d62..23a60d3d62 100644
--- a/patches/server/0665-Line-Of-Sight-Changes.patch
+++ b/patches/server/0668-Line-Of-Sight-Changes.patch
diff --git a/patches/server/0666-add-per-world-spawn-limits.patch b/patches/server/0669-add-per-world-spawn-limits.patch
index 3cc35c613b..b75079eb4c 100644
--- a/patches/server/0666-add-per-world-spawn-limits.patch
+++ b/patches/server/0669-add-per-world-spawn-limits.patch
@@ -6,10 +6,10 @@ Subject: [PATCH] add per world spawn limits
Taken from #2982. Credit to Chasewhip8
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-index 85972e19324027beaf215bed1b45947f976f5db4..59bf99a51d386851501b0acf2f07679f497d3132 100644
+index 5fbc8fabf1c94798c21035049f6585e915da0536..2bed5b4eaeac4e48df606b755489a3ca5ffc895e 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-@@ -211,6 +211,13 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+@@ -210,6 +210,13 @@ public class CraftWorld extends CraftRegionAccessor implements World {
this.biomeProvider = biomeProvider;
this.environment = env;
diff --git a/patches/server/0667-Fix-PotionSplashEvent-for-water-splash-potions.patch b/patches/server/0670-Fix-PotionSplashEvent-for-water-splash-potions.patch
index 56f02dad6e..56f02dad6e 100644
--- a/patches/server/0667-Fix-PotionSplashEvent-for-water-splash-potions.patch
+++ b/patches/server/0670-Fix-PotionSplashEvent-for-water-splash-potions.patch
diff --git a/patches/server/0668-Add-more-LimitedRegion-API.patch b/patches/server/0671-Add-more-LimitedRegion-API.patch
index e9e7611f99..e9e7611f99 100644
--- a/patches/server/0668-Add-more-LimitedRegion-API.patch
+++ b/patches/server/0671-Add-more-LimitedRegion-API.patch
diff --git a/patches/server/0669-Fix-PlayerDropItemEvent-using-wrong-item.patch b/patches/server/0672-Fix-PlayerDropItemEvent-using-wrong-item.patch
index 7d613a826d..7d613a826d 100644
--- a/patches/server/0669-Fix-PlayerDropItemEvent-using-wrong-item.patch
+++ b/patches/server/0672-Fix-PlayerDropItemEvent-using-wrong-item.patch
diff --git a/patches/server/0670-Missing-Entity-Behavior-API.patch b/patches/server/0673-Missing-Entity-Behavior-API.patch
index 6630ab2427..6630ab2427 100644
--- a/patches/server/0670-Missing-Entity-Behavior-API.patch
+++ b/patches/server/0673-Missing-Entity-Behavior-API.patch
diff --git a/patches/server/0671-Ensure-disconnect-for-book-edit-is-called-on-main.patch b/patches/server/0674-Ensure-disconnect-for-book-edit-is-called-on-main.patch
index 8dfe520cc0..8dfe520cc0 100644
--- a/patches/server/0671-Ensure-disconnect-for-book-edit-is-called-on-main.patch
+++ b/patches/server/0674-Ensure-disconnect-for-book-edit-is-called-on-main.patch
diff --git a/patches/server/0672-Fix-return-value-of-Block-applyBoneMeal-always-being.patch b/patches/server/0675-Fix-return-value-of-Block-applyBoneMeal-always-being.patch
index 863796fe03..863796fe03 100644
--- a/patches/server/0672-Fix-return-value-of-Block-applyBoneMeal-always-being.patch
+++ b/patches/server/0675-Fix-return-value-of-Block-applyBoneMeal-always-being.patch
diff --git a/patches/server/0673-Use-getChunkIfLoadedImmediately-in-places.patch b/patches/server/0676-Use-getChunkIfLoadedImmediately-in-places.patch
index fca57838c2..c6816f80a6 100644
--- a/patches/server/0673-Use-getChunkIfLoadedImmediately-in-places.patch
+++ b/patches/server/0676-Use-getChunkIfLoadedImmediately-in-places.patch
@@ -8,7 +8,7 @@ ticket level 33 (yes getChunkIfLoaded will actually perform a chunk
load in that case).
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index cfdf7d844390310f792cee93d6a149aa65bb7055..388958c9cdd366f8a5cdf7653abdcc6cdf5433ce 100644
+index 6e9f1f01227a94480043ba3120c77f1ae080ec02..d0c4c9c172c8caa3eaf6c0bf56a8be9f16d8c4e7 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -223,7 +223,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
@@ -20,7 +20,7 @@ index cfdf7d844390310f792cee93d6a149aa65bb7055..388958c9cdd366f8a5cdf7653abdcc6c
}
@Override
-@@ -1439,7 +1439,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -1441,7 +1441,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
for (int l1 = j; l1 <= i1; ++l1) {
for (int i2 = l; i2 <= k1; ++i2) {
diff --git a/patches/server/0674-Fix-commands-from-signs-not-firing-command-events.patch b/patches/server/0677-Fix-commands-from-signs-not-firing-command-events.patch
index c66c6d829d..c66c6d829d 100644
--- a/patches/server/0674-Fix-commands-from-signs-not-firing-command-events.patch
+++ b/patches/server/0677-Fix-commands-from-signs-not-firing-command-events.patch
diff --git a/patches/server/0675-Adds-PlayerArmSwingEvent.patch b/patches/server/0678-Adds-PlayerArmSwingEvent.patch
index be2b656c77..be2b656c77 100644
--- a/patches/server/0675-Adds-PlayerArmSwingEvent.patch
+++ b/patches/server/0678-Adds-PlayerArmSwingEvent.patch
diff --git a/patches/server/0676-Fixes-kick-event-leave-message-not-being-sent.patch b/patches/server/0679-Fixes-kick-event-leave-message-not-being-sent.patch
index 843edab18e..f8473df413 100644
--- a/patches/server/0676-Fixes-kick-event-leave-message-not-being-sent.patch
+++ b/patches/server/0679-Fixes-kick-event-leave-message-not-being-sent.patch
@@ -59,10 +59,10 @@ index 47043ebc5054a03ac56d171dc0c8c54bff0230c3..513a0e9c941a3ce7c3123d2476454ccc
this.server.getPlayerList().broadcastSystemMessage(PaperAdventure.asVanilla(quitMessage), false);
// Paper end
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
-index 07423d228b91d1482498c2e22bc23bf3ae997a38..f239acbf6ad778b06bbaf3e03aef9963e5467d0b 100644
+index cd7fdf629ac1dd17e83445afdf352c33823cbd25..a34df8db7ae5a1e2fd304e006db7b4af609efb4d 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
-@@ -601,6 +601,11 @@ public abstract class PlayerList {
+@@ -598,6 +598,11 @@ public abstract class PlayerList {
}
public net.kyori.adventure.text.Component remove(ServerPlayer entityplayer) { // Paper - return Component
@@ -74,7 +74,7 @@ index 07423d228b91d1482498c2e22bc23bf3ae997a38..f239acbf6ad778b06bbaf3e03aef9963
ServerLevel worldserver = entityplayer.getLevel();
entityplayer.awardStat(Stats.LEAVE_GAME);
-@@ -611,7 +616,7 @@ public abstract class PlayerList {
+@@ -608,7 +613,7 @@ public abstract class PlayerList {
entityplayer.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.DISCONNECT); // Paper
}
diff --git a/patches/server/0677-Add-config-for-mobs-immune-to-default-effects.patch b/patches/server/0680-Add-config-for-mobs-immune-to-default-effects.patch
index 600a8111cd..600a8111cd 100644
--- a/patches/server/0677-Add-config-for-mobs-immune-to-default-effects.patch
+++ b/patches/server/0680-Add-config-for-mobs-immune-to-default-effects.patch
diff --git a/patches/server/0678-Fix-incorrect-message-for-outdated-client.patch b/patches/server/0681-Fix-incorrect-message-for-outdated-client.patch
index 7f39718ca5..7f39718ca5 100644
--- a/patches/server/0678-Fix-incorrect-message-for-outdated-client.patch
+++ b/patches/server/0681-Fix-incorrect-message-for-outdated-client.patch
diff --git a/patches/server/0679-Don-t-apply-cramming-damage-to-players.patch b/patches/server/0682-Don-t-apply-cramming-damage-to-players.patch
index 28e1719c3c..28e1719c3c 100644
--- a/patches/server/0679-Don-t-apply-cramming-damage-to-players.patch
+++ b/patches/server/0682-Don-t-apply-cramming-damage-to-players.patch
diff --git a/patches/server/0680-Rate-options-and-timings-for-sensors-and-behaviors.patch b/patches/server/0683-Rate-options-and-timings-for-sensors-and-behaviors.patch
index 30867e6cf9..30867e6cf9 100644
--- a/patches/server/0680-Rate-options-and-timings-for-sensors-and-behaviors.patch
+++ b/patches/server/0683-Rate-options-and-timings-for-sensors-and-behaviors.patch
diff --git a/patches/server/0681-Add-a-bunch-of-missing-forceDrop-toggles.patch b/patches/server/0684-Add-a-bunch-of-missing-forceDrop-toggles.patch
index 34628f8969..34628f8969 100644
--- a/patches/server/0681-Add-a-bunch-of-missing-forceDrop-toggles.patch
+++ b/patches/server/0684-Add-a-bunch-of-missing-forceDrop-toggles.patch
diff --git a/patches/server/0682-Stinger-API.patch b/patches/server/0685-Stinger-API.patch
index 33f8959315..33f8959315 100644
--- a/patches/server/0682-Stinger-API.patch
+++ b/patches/server/0685-Stinger-API.patch
diff --git a/patches/server/0683-Fix-incosistency-issue-with-empty-map-items-in-CB.patch b/patches/server/0686-Fix-incosistency-issue-with-empty-map-items-in-CB.patch
index a58750b226..a58750b226 100644
--- a/patches/server/0683-Fix-incosistency-issue-with-empty-map-items-in-CB.patch
+++ b/patches/server/0686-Fix-incosistency-issue-with-empty-map-items-in-CB.patch
diff --git a/patches/server/0684-Add-System.out-err-catcher.patch b/patches/server/0687-Add-System.out-err-catcher.patch
index ce81957ca1..e2587514e8 100644
--- a/patches/server/0684-Add-System.out-err-catcher.patch
+++ b/patches/server/0687-Add-System.out-err-catcher.patch
@@ -105,7 +105,7 @@ index 0000000000000000000000000000000000000000..76d0d00cd6742991e3f3ec827a75ee87
+ }
+}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-index 96e207db7c06f02bdcae9af482bf2d36b5baee9b..589ee4fd2a7f2c81ef0324662d8349cd3105373f 100644
+index dd43414dde55a5b447f9f51e4e5eef12fbbcfbde..e7863390c8394a6afcfa25099b4ce49c5e010f13 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -284,6 +284,7 @@ public final class CraftServer implements Server {
diff --git a/patches/server/0685-Fix-test-not-bootstrapping.patch b/patches/server/0688-Fix-test-not-bootstrapping.patch
index 5d0466c3b3..5d0466c3b3 100644
--- a/patches/server/0685-Fix-test-not-bootstrapping.patch
+++ b/patches/server/0688-Fix-test-not-bootstrapping.patch
diff --git a/patches/server/0686-Rewrite-LogEvents-to-contain-the-source-jars-in-stac.patch b/patches/server/0689-Rewrite-LogEvents-to-contain-the-source-jars-in-stac.patch
index 10cd90749d..10cd90749d 100644
--- a/patches/server/0686-Rewrite-LogEvents-to-contain-the-source-jars-in-stac.patch
+++ b/patches/server/0689-Rewrite-LogEvents-to-contain-the-source-jars-in-stac.patch
diff --git a/patches/server/0687-Improve-boat-collision-performance.patch b/patches/server/0690-Improve-boat-collision-performance.patch
index 242644a66c..242644a66c 100644
--- a/patches/server/0687-Improve-boat-collision-performance.patch
+++ b/patches/server/0690-Improve-boat-collision-performance.patch
diff --git a/patches/server/0688-Prevent-AFK-kick-while-watching-end-credits.patch b/patches/server/0691-Prevent-AFK-kick-while-watching-end-credits.patch
index ac9275d800..ac9275d800 100644
--- a/patches/server/0688-Prevent-AFK-kick-while-watching-end-credits.patch
+++ b/patches/server/0691-Prevent-AFK-kick-while-watching-end-credits.patch
diff --git a/patches/server/0689-Allow-skipping-writing-of-comments-to-server.propert.patch b/patches/server/0692-Allow-skipping-writing-of-comments-to-server.propert.patch
index 6395f3f4a8..6395f3f4a8 100644
--- a/patches/server/0689-Allow-skipping-writing-of-comments-to-server.propert.patch
+++ b/patches/server/0692-Allow-skipping-writing-of-comments-to-server.propert.patch
diff --git a/patches/server/0690-Add-PlayerSetSpawnEvent.patch b/patches/server/0693-Add-PlayerSetSpawnEvent.patch
index 8fc9df37b8..e726d70f85 100644
--- a/patches/server/0690-Add-PlayerSetSpawnEvent.patch
+++ b/patches/server/0693-Add-PlayerSetSpawnEvent.patch
@@ -89,10 +89,10 @@ index 56ac440465813a7dab8d166e882e18143a50729f..80e1970f568a74a43e624188a77cfbd2
public void trackChunk(ChunkPos chunkPos, Packet<?> chunkDataPacket) {
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
-index f239acbf6ad778b06bbaf3e03aef9963e5467d0b..66dcd4141ee3b650c4e7a6de2456eb3eb19ea287 100644
+index a34df8db7ae5a1e2fd304e006db7b4af609efb4d..5ee0c3bb27ffbadc1e088983e643eed974753b65 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
-@@ -905,13 +905,13 @@ public abstract class PlayerList {
+@@ -902,13 +902,13 @@ public abstract class PlayerList {
f1 = (float) Mth.wrapDegrees(Mth.atan2(vec3d1.z, vec3d1.x) * 57.2957763671875D - 90.0D);
}
@@ -129,10 +129,10 @@ index c3e49a781f838e6a46cb89744f3f1846de182275..c2f3d3a09327e7cb7d3167609eb3ce68
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
-index 4750ac09f2abfb712b042028a95d23121ffc049f..d309c994ffd72952cf9a8f2f4cc21231417bb9ed 100644
+index a7a0b892b50302ac7af4588bb65206834134dba2..5cdb599c6e460672ed0fe15d5c2a9d60ad22c2e3 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
-@@ -1216,9 +1216,9 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
+@@ -1206,9 +1206,9 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
@Override
public void setBedSpawnLocation(Location location, boolean override) {
if (location == null) {
diff --git a/patches/server/0691-Make-hoppers-respect-inventory-max-stack-size.patch b/patches/server/0694-Make-hoppers-respect-inventory-max-stack-size.patch
index b4a083a5f7..b4a083a5f7 100644
--- a/patches/server/0691-Make-hoppers-respect-inventory-max-stack-size.patch
+++ b/patches/server/0694-Make-hoppers-respect-inventory-max-stack-size.patch
diff --git a/patches/server/0692-Optimize-entity-tracker-passenger-checks.patch b/patches/server/0695-Optimize-entity-tracker-passenger-checks.patch
index d3fef67200..d3fef67200 100644
--- a/patches/server/0692-Optimize-entity-tracker-passenger-checks.patch
+++ b/patches/server/0695-Optimize-entity-tracker-passenger-checks.patch
diff --git a/patches/server/0693-Config-option-for-Piglins-guarding-chests.patch b/patches/server/0696-Config-option-for-Piglins-guarding-chests.patch
index c66e6ea022..c66e6ea022 100644
--- a/patches/server/0693-Config-option-for-Piglins-guarding-chests.patch
+++ b/patches/server/0696-Config-option-for-Piglins-guarding-chests.patch
diff --git a/patches/server/0694-Added-EntityDamageItemEvent.patch b/patches/server/0697-Added-EntityDamageItemEvent.patch
index ec43bd00c9..ec43bd00c9 100644
--- a/patches/server/0694-Added-EntityDamageItemEvent.patch
+++ b/patches/server/0697-Added-EntityDamageItemEvent.patch
diff --git a/patches/server/0695-Optimize-indirect-passenger-iteration.patch b/patches/server/0698-Optimize-indirect-passenger-iteration.patch
index 6ae8c4e698..6ae8c4e698 100644
--- a/patches/server/0695-Optimize-indirect-passenger-iteration.patch
+++ b/patches/server/0698-Optimize-indirect-passenger-iteration.patch
diff --git a/patches/server/0696-Fix-block-drops-position-losing-precision-millions-o.patch b/patches/server/0699-Fix-block-drops-position-losing-precision-millions-o.patch
index 6b5cd596c4..6b5cd596c4 100644
--- a/patches/server/0696-Fix-block-drops-position-losing-precision-millions-o.patch
+++ b/patches/server/0699-Fix-block-drops-position-losing-precision-millions-o.patch
diff --git a/patches/server/0697-Configurable-item-frame-map-cursor-update-interval.patch b/patches/server/0700-Configurable-item-frame-map-cursor-update-interval.patch
index 5e1d739a7c..5e1d739a7c 100644
--- a/patches/server/0697-Configurable-item-frame-map-cursor-update-interval.patch
+++ b/patches/server/0700-Configurable-item-frame-map-cursor-update-interval.patch
diff --git a/patches/server/0698-Make-EntityUnleashEvent-cancellable.patch b/patches/server/0701-Make-EntityUnleashEvent-cancellable.patch
index 10b64ca856..10b64ca856 100644
--- a/patches/server/0698-Make-EntityUnleashEvent-cancellable.patch
+++ b/patches/server/0701-Make-EntityUnleashEvent-cancellable.patch
diff --git a/patches/server/0699-Clear-bucket-NBT-after-dispense.patch b/patches/server/0702-Clear-bucket-NBT-after-dispense.patch
index 52e26f4674..52e26f4674 100644
--- a/patches/server/0699-Clear-bucket-NBT-after-dispense.patch
+++ b/patches/server/0702-Clear-bucket-NBT-after-dispense.patch
diff --git a/patches/server/0700-Change-EnderEye-target-without-changing-other-things.patch b/patches/server/0703-Change-EnderEye-target-without-changing-other-things.patch
index ce9dc32309..ce9dc32309 100644
--- a/patches/server/0700-Change-EnderEye-target-without-changing-other-things.patch
+++ b/patches/server/0703-Change-EnderEye-target-without-changing-other-things.patch
diff --git a/patches/server/0701-Add-BlockBreakBlockEvent.patch b/patches/server/0704-Add-BlockBreakBlockEvent.patch
index a69de03ab7..a69de03ab7 100644
--- a/patches/server/0701-Add-BlockBreakBlockEvent.patch
+++ b/patches/server/0704-Add-BlockBreakBlockEvent.patch
diff --git a/patches/server/0702-Option-to-prevent-NBT-copy-in-smithing-recipes.patch b/patches/server/0705-Option-to-prevent-NBT-copy-in-smithing-recipes.patch
index 14e666a79e..14e666a79e 100644
--- a/patches/server/0702-Option-to-prevent-NBT-copy-in-smithing-recipes.patch
+++ b/patches/server/0705-Option-to-prevent-NBT-copy-in-smithing-recipes.patch
diff --git a/patches/server/0703-More-CommandBlock-API.patch b/patches/server/0706-More-CommandBlock-API.patch
index 3cbd2436d3..3cbd2436d3 100644
--- a/patches/server/0703-More-CommandBlock-API.patch
+++ b/patches/server/0706-More-CommandBlock-API.patch
diff --git a/patches/server/0704-Add-missing-team-sidebar-display-slots.patch b/patches/server/0707-Add-missing-team-sidebar-display-slots.patch
index ee0f1ced64..ee0f1ced64 100644
--- a/patches/server/0704-Add-missing-team-sidebar-display-slots.patch
+++ b/patches/server/0707-Add-missing-team-sidebar-display-slots.patch
diff --git a/patches/server/0705-Add-back-EntityPortalExitEvent.patch b/patches/server/0708-Add-back-EntityPortalExitEvent.patch
index 79c8ecd49d..79c8ecd49d 100644
--- a/patches/server/0705-Add-back-EntityPortalExitEvent.patch
+++ b/patches/server/0708-Add-back-EntityPortalExitEvent.patch
diff --git a/patches/server/0706-Add-methods-to-find-targets-for-lightning-strikes.patch b/patches/server/0709-Add-methods-to-find-targets-for-lightning-strikes.patch
index f76a939dc1..6880c6cd68 100644
--- a/patches/server/0706-Add-methods-to-find-targets-for-lightning-strikes.patch
+++ b/patches/server/0709-Add-methods-to-find-targets-for-lightning-strikes.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Add methods to find targets for lightning strikes
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index 388958c9cdd366f8a5cdf7653abdcc6cdf5433ce..290f7253e78bfd3acdffd2ca6368d80c8620eba5 100644
+index d0c4c9c172c8caa3eaf6c0bf56a8be9f16d8c4e7..10421fdac40c756c52abc9430f7149a9f58efbfb 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
-@@ -778,6 +778,11 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -780,6 +780,11 @@ public class ServerLevel extends Level implements WorldGenLevel {
}
protected BlockPos findLightningTargetAround(BlockPos pos) {
@@ -20,7 +20,7 @@ index 388958c9cdd366f8a5cdf7653abdcc6cdf5433ce..290f7253e78bfd3acdffd2ca6368d80c
BlockPos blockposition1 = this.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, pos);
Optional<BlockPos> optional = this.findLightningRod(blockposition1);
-@@ -792,6 +797,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -794,6 +799,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
if (!list.isEmpty()) {
return ((LivingEntity) list.get(this.random.nextInt(list.size()))).blockPosition();
} else {
@@ -29,10 +29,10 @@ index 388958c9cdd366f8a5cdf7653abdcc6cdf5433ce..290f7253e78bfd3acdffd2ca6368d80c
blockposition1 = blockposition1.above(2);
}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-index 59bf99a51d386851501b0acf2f07679f497d3132..9d3f7f196c4331662c4c78cac0b047bcd2ff5e77 100644
+index 2bed5b4eaeac4e48df606b755489a3ca5ffc895e..38a74d683aec58a419af84111844a205596524b2 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-@@ -697,6 +697,23 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+@@ -696,6 +696,23 @@ public class CraftWorld extends CraftRegionAccessor implements World {
return (LightningStrike) lightning.getBukkitEntity();
}
diff --git a/patches/server/0707-Get-entity-default-attributes.patch b/patches/server/0710-Get-entity-default-attributes.patch
index c2cbc0160d..c2cbc0160d 100644
--- a/patches/server/0707-Get-entity-default-attributes.patch
+++ b/patches/server/0710-Get-entity-default-attributes.patch
diff --git a/patches/server/0708-Left-handed-API.patch b/patches/server/0711-Left-handed-API.patch
index 8a6c26a272..8a6c26a272 100644
--- a/patches/server/0708-Left-handed-API.patch
+++ b/patches/server/0711-Left-handed-API.patch
diff --git a/patches/server/0709-Add-advancement-display-API.patch b/patches/server/0712-Add-advancement-display-API.patch
index dd860e3b4d..dd860e3b4d 100644
--- a/patches/server/0709-Add-advancement-display-API.patch
+++ b/patches/server/0712-Add-advancement-display-API.patch
diff --git a/patches/server/0710-Add-ItemFactory-getMonsterEgg-API.patch b/patches/server/0713-Add-ItemFactory-getMonsterEgg-API.patch
index 1944914081..1944914081 100644
--- a/patches/server/0710-Add-ItemFactory-getMonsterEgg-API.patch
+++ b/patches/server/0713-Add-ItemFactory-getMonsterEgg-API.patch
diff --git a/patches/server/0711-Add-critical-damage-API.patch b/patches/server/0714-Add-critical-damage-API.patch
index 980b435d42..980b435d42 100644
--- a/patches/server/0711-Add-critical-damage-API.patch
+++ b/patches/server/0714-Add-critical-damage-API.patch
diff --git a/patches/server/0712-Fix-issues-with-mob-conversion.patch b/patches/server/0715-Fix-issues-with-mob-conversion.patch
index 69feb4b3a4..69feb4b3a4 100644
--- a/patches/server/0712-Fix-issues-with-mob-conversion.patch
+++ b/patches/server/0715-Fix-issues-with-mob-conversion.patch
diff --git a/patches/server/0713-Add-isCollidable-methods-to-various-places.patch b/patches/server/0716-Add-isCollidable-methods-to-various-places.patch
index 2b95e405a3..2b95e405a3 100644
--- a/patches/server/0713-Add-isCollidable-methods-to-various-places.patch
+++ b/patches/server/0716-Add-isCollidable-methods-to-various-places.patch
diff --git a/patches/server/0714-Goat-ram-API.patch b/patches/server/0717-Goat-ram-API.patch
index 426746ea8f..426746ea8f 100644
--- a/patches/server/0714-Goat-ram-API.patch
+++ b/patches/server/0717-Goat-ram-API.patch
diff --git a/patches/server/0715-Add-API-for-resetting-a-single-score.patch b/patches/server/0718-Add-API-for-resetting-a-single-score.patch
index c2e1fd93b9..c2e1fd93b9 100644
--- a/patches/server/0715-Add-API-for-resetting-a-single-score.patch
+++ b/patches/server/0718-Add-API-for-resetting-a-single-score.patch
diff --git a/patches/server/0716-Add-Raw-Byte-Entity-Serialization.patch b/patches/server/0719-Add-Raw-Byte-Entity-Serialization.patch
index 2f27482d7e..a4fbf9a562 100644
--- a/patches/server/0716-Add-Raw-Byte-Entity-Serialization.patch
+++ b/patches/server/0719-Add-Raw-Byte-Entity-Serialization.patch
@@ -25,7 +25,7 @@ index 3f4436a2257376f604926ff35c8589ba59c859e2..6f3147713b5bec3b2771e1ec52917fd4
return this.isPassenger() ? false : this.saveAsPassenger(nbt);
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
-index b8e5205c165bcba5b8383334f3d0d1daf9d0a8cd..ff8562821ebb363c755e9d316679226d9febe54f 100644
+index e9828bab16ac05babccfb1fefad85860c1a4768c..f04dcefde38c03403f05305ef044b0ee7608eaa3 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
@@ -1295,5 +1295,15 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
diff --git a/patches/server/0717-Vanilla-command-permission-fixes.patch b/patches/server/0720-Vanilla-command-permission-fixes.patch
index 8e3102cba2..603bc9d5f0 100644
--- a/patches/server/0717-Vanilla-command-permission-fixes.patch
+++ b/patches/server/0720-Vanilla-command-permission-fixes.patch
@@ -30,7 +30,7 @@ index 899008b2980d13f1be6280cd8cb959c53a29bebf..f875507241ac6769545e91cd3285232b
private RedirectModifier<S> modifier = null;
private boolean forks;
diff --git a/src/main/java/net/minecraft/commands/Commands.java b/src/main/java/net/minecraft/commands/Commands.java
-index 884a7c3a082140d2e1d154851c534ab09f5da4ce..6d480d0332ee9348eacc3269890ee49206623c2a 100644
+index 9c0b2679964f864671ff4041163d1065c8d9cf84..27093aed1f4112a5414671fd5d9c4e683011506d 100644
--- a/src/main/java/net/minecraft/commands/Commands.java
+++ b/src/main/java/net/minecraft/commands/Commands.java
@@ -212,7 +212,13 @@ public class Commands {
diff --git a/patches/server/0719-Do-not-allow-the-server-to-unload-chunks-at-request-.patch b/patches/server/0721-Do-not-allow-the-server-to-unload-chunks-at-request-.patch
index 169dae61cc..f8339eb67a 100644
--- a/patches/server/0719-Do-not-allow-the-server-to-unload-chunks-at-request-.patch
+++ b/patches/server/0721-Do-not-allow-the-server-to-unload-chunks-at-request-.patch
@@ -10,10 +10,10 @@ to be unloaded will simply be unloaded next tick, rather than
immediately.
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
-index 918fda0fbbafa39ce0f421dcaf10f8dcf1e5dabb..30347bba40c77c95933997800b9149fcd2326bb1 100644
+index 15b275ee91451478d1c55eae0d20e0e8f36f3a0f..dd4656f0b9d7740ab449ede2588df64e647fab40 100644
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
-@@ -873,6 +873,7 @@ public class ServerChunkCache extends ChunkSource {
+@@ -694,6 +694,7 @@ public class ServerChunkCache extends ChunkSource {
// CraftBukkit start - modelled on below
public void purgeUnload() {
diff --git a/patches/server/0720-Do-not-run-close-logic-for-inventories-on-chunk-unlo.patch b/patches/server/0722-Do-not-run-close-logic-for-inventories-on-chunk-unlo.patch
index aae72845be..c4c28b34ad 100644
--- a/patches/server/0720-Do-not-run-close-logic-for-inventories-on-chunk-unlo.patch
+++ b/patches/server/0722-Do-not-run-close-logic-for-inventories-on-chunk-unlo.patch
@@ -9,10 +9,10 @@ chunk through it. This should also be OK from a leak prevention/
state desync POV because the TE is getting unloaded anyways.
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index 290f7253e78bfd3acdffd2ca6368d80c8620eba5..8234f7edb7668c9e9e742d703a3db315aa523fb4 100644
+index 10421fdac40c756c52abc9430f7149a9f58efbfb..39d96b4e3dce6d67b568b7b00456de164f6a7241 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
-@@ -1336,9 +1336,13 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -1338,9 +1338,13 @@ public class ServerLevel extends Level implements WorldGenLevel {
// Spigot Start
for (net.minecraft.world.level.block.entity.BlockEntity tileentity : chunk.getBlockEntities().values()) {
if (tileentity instanceof net.minecraft.world.Container) {
diff --git a/patches/server/0721-Correctly-handle-recursion-for-chunkholder-updates.patch b/patches/server/0723-Correctly-handle-recursion-for-chunkholder-updates.patch
index f152c64ae6..17b34c16ac 100644
--- a/patches/server/0721-Correctly-handle-recursion-for-chunkholder-updates.patch
+++ b/patches/server/0723-Correctly-handle-recursion-for-chunkholder-updates.patch
@@ -8,10 +8,10 @@ cause a recursive call which would handle the increase but then
the caller would think the chunk would be unloaded.
diff --git a/src/main/java/net/minecraft/server/level/ChunkHolder.java b/src/main/java/net/minecraft/server/level/ChunkHolder.java
-index 96fb6e6ba3d1f9d5bd412f4f2bfb9450efa17948..eda3929ea7dee63c3598f676f719770637940f53 100644
+index c4046b364d1896b781e23c92b241ec73c239d3a0..9c0bf31c3c362632241c95338a3f8d67bbd4fdc5 100644
--- a/src/main/java/net/minecraft/server/level/ChunkHolder.java
+++ b/src/main/java/net/minecraft/server/level/ChunkHolder.java
-@@ -467,8 +467,10 @@ public class ChunkHolder {
+@@ -472,8 +472,10 @@ public class ChunkHolder {
playerchunkmap.onFullChunkStatusChange(this.pos, playerchunk_state);
}
@@ -22,7 +22,7 @@ index 96fb6e6ba3d1f9d5bd412f4f2bfb9450efa17948..eda3929ea7dee63c3598f676f7197706
ChunkStatus chunkstatus = ChunkHolder.getStatus(this.oldTicketLevel);
ChunkStatus chunkstatus1 = ChunkHolder.getStatus(this.ticketLevel);
boolean flag = this.oldTicketLevel <= ChunkMap.MAX_CHUNK_DISTANCE;
-@@ -510,6 +512,12 @@ public class ChunkHolder {
+@@ -515,6 +517,12 @@ public class ChunkHolder {
// Run callback right away if the future was already done
chunkStorage.callbackExecutor.run();
diff --git a/patches/server/0722-Fix-GameProfileCache-concurrency.patch b/patches/server/0724-Fix-GameProfileCache-concurrency.patch
index 68ce86c24e..68ce86c24e 100644
--- a/patches/server/0722-Fix-GameProfileCache-concurrency.patch
+++ b/patches/server/0724-Fix-GameProfileCache-concurrency.patch
diff --git a/patches/server/0723-Fix-chunks-refusing-to-unload-at-low-TPS.patch b/patches/server/0725-Fix-chunks-refusing-to-unload-at-low-TPS.patch
index bbdf10fb3e..27155400d9 100644
--- a/patches/server/0723-Fix-chunks-refusing-to-unload-at-low-TPS.patch
+++ b/patches/server/0725-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/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
-index 2418f1c0dc050d224bb866e62f414a55900d9652..f29d77572a3cd977fc492ada8ffc8b77467fabc5 100644
+index 5a78ee69748b2b7b57a9adcff0a4718b1cc0c4ea..a3fceb2608b3be80941dfe2570999b270429e0c6 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
-@@ -1328,9 +1328,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -1352,9 +1352,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
return chunk;
});
diff --git a/patches/server/0724-Do-not-allow-ticket-level-changes-while-unloading-pl.patch b/patches/server/0726-Do-not-allow-ticket-level-changes-while-unloading-pl.patch
index 5a943a25f6..853e534c5c 100644
--- a/patches/server/0724-Do-not-allow-ticket-level-changes-while-unloading-pl.patch
+++ b/patches/server/0726-Do-not-allow-ticket-level-changes-while-unloading-pl.patch
@@ -8,18 +8,18 @@ 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/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
-index f29d77572a3cd977fc492ada8ffc8b77467fabc5..ae0d7295c88005749f13dd230136f4a39d0a578e 100644
+index a3fceb2608b3be80941dfe2570999b270429e0c6..b34c90497a5492c289839ba74df9f2f27e29370e 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
-@@ -314,6 +314,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -316,6 +316,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
}
// Paper end
+ boolean unloadingPlayerChunk = false; // Paper - do not allow ticket level changes while unloading chunks
public ChunkMap(ServerLevel world, LevelStorageSource.LevelStorageAccess session, DataFixer dataFixer, StructureTemplateManager structureTemplateManager, Executor executor, BlockableEventLoop<Runnable> mainThreadExecutor, LightChunkGetter chunkProvider, ChunkGenerator chunkGenerator, ChunkProgressListener worldGenerationProgressListener, ChunkStatusUpdateListener chunkStatusChangeListener, Supplier<DimensionDataStorage> persistentStateManagerFactory, int viewDistance, boolean dsync) {
super(session.getDimensionPath(world.dimension()).resolve("region"), dataFixer, dsync);
- this.visibleChunkMap = this.updatingChunkMap.clone();
-@@ -725,6 +726,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+ // Paper - don't copy
+@@ -731,6 +732,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
@Nullable
ChunkHolder updateChunkScheduling(long pos, int level, @Nullable ChunkHolder holder, int k) {
@@ -27,7 +27,7 @@ index f29d77572a3cd977fc492ada8ffc8b77467fabc5..ae0d7295c88005749f13dd230136f4a3
if (k > ChunkMap.MAX_CHUNK_DISTANCE && level > ChunkMap.MAX_CHUNK_DISTANCE) {
return holder;
} else {
-@@ -928,6 +930,12 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -945,6 +947,12 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
if (completablefuture1 != completablefuture) {
this.scheduleUnload(pos, holder);
} else {
@@ -40,19 +40,19 @@ index f29d77572a3cd977fc492ada8ffc8b77467fabc5..ae0d7295c88005749f13dd230136f4a3
// Paper start
boolean removed;
if ((removed = this.pendingUnloads.remove(pos, holder)) && ichunkaccess != null) {
-@@ -965,6 +973,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
- this.regionManagers.get(index).removeChunk(holder.pos.x, holder.pos.z);
- }
- } // Paper end
+@@ -978,6 +986,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+ } else if (removed) { // Paper start
+ net.minecraft.server.ChunkSystem.onChunkHolderDelete(this.level, holder);
+ } // Paper end
+ } finally { this.unloadingPlayerChunk = unloadingBefore; } // Paper - do not allow ticket level changes while unloading chunks
}
};
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
-index 30347bba40c77c95933997800b9149fcd2326bb1..591c9577a66f5663f7728b70f44e33ca029af085 100644
+index dd4656f0b9d7740ab449ede2588df64e647fab40..3e45d0c1a95cf8124d15ff4851ea1dcf063f440d 100644
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
-@@ -809,6 +809,7 @@ public class ServerChunkCache extends ChunkSource {
+@@ -630,6 +630,7 @@ public class ServerChunkCache extends ChunkSource {
public boolean runDistanceManagerUpdates() {
if (distanceManager.delayDistanceManagerTick) return false; // Paper - Chunk priority
diff --git a/patches/server/0725-Do-not-allow-ticket-level-changes-when-updating-chun.patch b/patches/server/0727-Do-not-allow-ticket-level-changes-when-updating-chun.patch
index c863630ea8..d3e3677642 100644
--- a/patches/server/0725-Do-not-allow-ticket-level-changes-when-updating-chun.patch
+++ b/patches/server/0727-Do-not-allow-ticket-level-changes-when-updating-chun.patch
@@ -8,10 +8,10 @@ This WILL cause state corruption if it happens. So, don't
allow it.
diff --git a/src/main/java/net/minecraft/server/level/ChunkHolder.java b/src/main/java/net/minecraft/server/level/ChunkHolder.java
-index eda3929ea7dee63c3598f676f719770637940f53..b75b3c4d274252a3a5c53059b9702728eeada389 100644
+index 9c0bf31c3c362632241c95338a3f8d67bbd4fdc5..a2b5f6457b08e4e02544dc71fbf383b5a67a2d69 100644
--- a/src/main/java/net/minecraft/server/level/ChunkHolder.java
+++ b/src/main/java/net/minecraft/server/level/ChunkHolder.java
-@@ -447,7 +447,13 @@ public class ChunkHolder {
+@@ -452,7 +452,13 @@ public class ChunkHolder {
CompletableFuture<Void> completablefuture1 = new CompletableFuture();
completablefuture1.thenRunAsync(() -> {
@@ -25,7 +25,7 @@ index eda3929ea7dee63c3598f676f719770637940f53..b75b3c4d274252a3a5c53059b9702728
}, executor);
this.pendingFullStateConfirmation = completablefuture1;
completablefuture.thenAccept((either) -> {
-@@ -464,7 +470,12 @@ public class ChunkHolder {
+@@ -469,7 +475,12 @@ public class ChunkHolder {
private void demoteFullChunk(ChunkMap playerchunkmap, ChunkHolder.FullChunkStatus playerchunk_state) {
this.pendingFullStateConfirmation.cancel(false);
diff --git a/patches/server/0726-Log-when-the-async-catcher-is-tripped.patch b/patches/server/0728-Log-when-the-async-catcher-is-tripped.patch
index bede76faf6..bede76faf6 100644
--- a/patches/server/0726-Log-when-the-async-catcher-is-tripped.patch
+++ b/patches/server/0728-Log-when-the-async-catcher-is-tripped.patch
diff --git a/patches/server/0727-Add-paper-mobcaps-and-paper-playermobcaps.patch b/patches/server/0729-Add-paper-mobcaps-and-paper-playermobcaps.patch
index 3e6c326057..07f2b36a13 100644
--- a/patches/server/0727-Add-paper-mobcaps-and-paper-playermobcaps.patch
+++ b/patches/server/0729-Add-paper-mobcaps-and-paper-playermobcaps.patch
@@ -286,7 +286,7 @@ index fa23e9c476d4edc6176d8b8a6cb13c52d2f66a87..4150e8cd7197eac53042d56f0a53a495
// Paper start - add parameters and int ret type
spawnCategoryForChunk(group, world, chunk, checker, runner, Integer.MAX_VALUE, null);
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-index 589ee4fd2a7f2c81ef0324662d8349cd3105373f..7f874c53cdb1815e3337c51ab564b7dafb20c939 100644
+index e7863390c8394a6afcfa25099b4ce49c5e010f13..4adacf6f849fe41918690fb8f195727a9c880b53 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -2156,6 +2156,11 @@ public final class CraftServer implements Server {
@@ -302,10 +302,10 @@ index 589ee4fd2a7f2c81ef0324662d8349cd3105373f..7f874c53cdb1815e3337c51ab564b7da
}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-index 9d3f7f196c4331662c4c78cac0b047bcd2ff5e77..21bf39ef5b20ecc989881b07c4e6b90c68540afd 100644
+index 38a74d683aec58a419af84111844a205596524b2..5138182d8004aec69848d10b8cc63453c1e8808f 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-@@ -1712,9 +1712,14 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+@@ -1711,9 +1711,14 @@ public class CraftWorld extends CraftRegionAccessor implements World {
Validate.notNull(spawnCategory, "SpawnCategory cannot be null");
Validate.isTrue(CraftSpawnCategory.isValidForLimits(spawnCategory), "SpawnCategory." + spawnCategory + " are not supported.");
diff --git a/patches/server/0728-Prevent-unload-calls-removing-tickets-for-sync-loads.patch b/patches/server/0730-Prevent-unload-calls-removing-tickets-for-sync-loads.patch
index a8485996ae..5c819b2c69 100644
--- a/patches/server/0728-Prevent-unload-calls-removing-tickets-for-sync-loads.patch
+++ b/patches/server/0730-Prevent-unload-calls-removing-tickets-for-sync-loads.patch
@@ -18,10 +18,10 @@ index b2df5e18ce5260a9781052db7afb0b9786fb887c..537d34a0325a985948c744929b90144a
while (objectiterator.hasNext()) {
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
-index 591c9577a66f5663f7728b70f44e33ca029af085..ce88da358c8a89564a911e6c818e906e845006ff 100644
+index 3e45d0c1a95cf8124d15ff4851ea1dcf063f440d..9f7ec687e6cf971bb9699e9f4ad7ebe37a3ef882 100644
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
-@@ -714,6 +714,8 @@ public class ServerChunkCache extends ChunkSource {
+@@ -535,6 +535,8 @@ public class ServerChunkCache extends ChunkSource {
return completablefuture;
}
@@ -30,7 +30,7 @@ index 591c9577a66f5663f7728b70f44e33ca029af085..ce88da358c8a89564a911e6c818e906e
private CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> getChunkFutureMainThread(int chunkX, int chunkZ, ChunkStatus leastStatus, boolean create) {
// Paper start - add isUrgent - old sig left in place for dirty nms plugins
return getChunkFutureMainThread(chunkX, chunkZ, leastStatus, create, false);
-@@ -732,9 +734,12 @@ public class ServerChunkCache extends ChunkSource {
+@@ -553,9 +555,12 @@ public class ServerChunkCache extends ChunkSource {
ChunkHolder.FullChunkStatus currentChunkState = ChunkHolder.getFullChunkStatus(playerchunk.getTicketLevel());
currentlyUnloading = (oldChunkState.isOrAfter(ChunkHolder.FullChunkStatus.BORDER) && !currentChunkState.isOrAfter(ChunkHolder.FullChunkStatus.BORDER));
}
@@ -43,7 +43,7 @@ index 591c9577a66f5663f7728b70f44e33ca029af085..ce88da358c8a89564a911e6c818e906e
if (isUrgent) this.distanceManager.markUrgent(chunkcoordintpair); // Paper - Chunk priority
if (this.chunkAbsent(playerchunk, l)) {
ProfilerFiller gameprofilerfiller = this.level.getProfiler();
-@@ -745,13 +750,21 @@ public class ServerChunkCache extends ChunkSource {
+@@ -566,13 +571,21 @@ public class ServerChunkCache extends ChunkSource {
playerchunk = this.getVisibleChunkIfPresent(k);
gameprofilerfiller.pop();
if (this.chunkAbsent(playerchunk, l)) {
diff --git a/patches/server/0729-Sanitize-ResourceLocation-error-logging.patch b/patches/server/0731-Sanitize-ResourceLocation-error-logging.patch
index c2ff3a02e4..c2ff3a02e4 100644
--- a/patches/server/0729-Sanitize-ResourceLocation-error-logging.patch
+++ b/patches/server/0731-Sanitize-ResourceLocation-error-logging.patch
diff --git a/patches/server/0730-Allow-controlled-flushing-for-network-manager.patch b/patches/server/0732-Allow-controlled-flushing-for-network-manager.patch
index cbd07781ef..cbd07781ef 100644
--- a/patches/server/0730-Allow-controlled-flushing-for-network-manager.patch
+++ b/patches/server/0732-Allow-controlled-flushing-for-network-manager.patch
diff --git a/patches/server/0731-Optimise-general-POI-access.patch b/patches/server/0733-Optimise-general-POI-access.patch
index b7014db094..b7014db094 100644
--- a/patches/server/0731-Optimise-general-POI-access.patch
+++ b/patches/server/0733-Optimise-general-POI-access.patch
diff --git a/patches/server/0732-Add-more-async-catchers.patch b/patches/server/0734-Add-more-async-catchers.patch
index 30eca154ba..c455647bca 100644
--- a/patches/server/0732-Add-more-async-catchers.patch
+++ b/patches/server/0734-Add-more-async-catchers.patch
@@ -31,10 +31,10 @@ index 2830d32bba3dc85847e3a5d9b4d98f822e34b606..a176a886235494fdc722030a93658d36
throw new UnsupportedOperationException("Only one concurrent iteration supported");
} else {
diff --git a/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java b/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java
-index e53e912351a0753c429512f018281a656837bde2..fcf85047d89d5c55df78ab2a6d81cb6da254ecd7 100644
+index a5dc8e715c86c1e70a9cf3d99c9cd457a6666b70..a1a52669c19af22e3b5267d43584cb00d1646453 100644
--- a/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java
+++ b/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java
-@@ -166,6 +166,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
+@@ -178,6 +178,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
}
public void updateChunkStatus(ChunkPos chunkPos, ChunkHolder.FullChunkStatus levelType) {
diff --git a/patches/server/0733-Rewrite-entity-bounding-box-lookup-calls.patch b/patches/server/0735-Rewrite-entity-bounding-box-lookup-calls.patch
index b9ac3b1401..7f57f555d0 100644
--- a/patches/server/0733-Rewrite-entity-bounding-box-lookup-calls.patch
+++ b/patches/server/0735-Rewrite-entity-bounding-box-lookup-calls.patch
@@ -914,10 +914,10 @@ index 0000000000000000000000000000000000000000..3ba094e640d7fe7803e2bbdab8ff3beb
+ }
+}
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index 8234f7edb7668c9e9e742d703a3db315aa523fb4..f3aa1276f0689996ce7827c9300c141dd95582cc 100644
+index 39d96b4e3dce6d67b568b7b00456de164f6a7241..29b80d074600fa7e20b05d1fe70ac12969b954a4 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
-@@ -452,7 +452,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -454,7 +454,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
DataFixer datafixer = minecraftserver.getFixerUpper();
EntityPersistentStorage<Entity> entitypersistentstorage = new EntityStorage(this, convertable_conversionsession.getDimensionPath(resourcekey).resolve("entities"), datafixer, flag2, minecraftserver);
@@ -1181,7 +1181,7 @@ index 2a4e6c6f732d9cd2567352b7fca2c284b0bb9c1b..4f484e71c93a5243d242e116e2f204ea
+ // Paper end
}
diff --git a/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java b/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java
-index fcf85047d89d5c55df78ab2a6d81cb6da254ecd7..8ad1c6f8147cfbd4677252a0d76f147786babe59 100644
+index a1a52669c19af22e3b5267d43584cb00d1646453..f635b610e68d129aa0ae60c54b83da6943946436 100644
--- a/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java
+++ b/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java
@@ -49,8 +49,10 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
@@ -1196,7 +1196,7 @@ index fcf85047d89d5c55df78ab2a6d81cb6da254ecd7..8ad1c6f8147cfbd4677252a0d76f1477
this.sectionStorage = new EntitySectionStorage<>(entityClass, this.chunkVisibility);
this.chunkVisibility.defaultReturnValue(Visibility.HIDDEN);
this.chunkLoadStatuses.defaultReturnValue(PersistentEntitySectionManager.ChunkLoadStatus.FRESH);
-@@ -112,6 +114,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
+@@ -124,6 +126,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
EntitySection<T> entitysection = this.sectionStorage.getOrCreateSection(i);
entitysection.add(entity);
@@ -1204,7 +1204,7 @@ index fcf85047d89d5c55df78ab2a6d81cb6da254ecd7..8ad1c6f8147cfbd4677252a0d76f1477
entity.setLevelCallback(new PersistentEntitySectionManager.Callback(entity, i, entitysection));
if (!existing) {
this.callbacks.onCreated(entity);
-@@ -169,6 +172,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
+@@ -181,6 +184,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
io.papermc.paper.util.TickThread.ensureTickThread("Asynchronous chunk ticking status update"); // Paper
Visibility visibility = Visibility.fromFullChunkStatus(levelType);
@@ -1212,7 +1212,7 @@ index fcf85047d89d5c55df78ab2a6d81cb6da254ecd7..8ad1c6f8147cfbd4677252a0d76f1477
this.updateChunkStatus(chunkPos, visibility);
}
-@@ -455,6 +459,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
+@@ -467,6 +471,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
long i = SectionPos.asLong(blockposition);
if (i != this.currentSectionKey) {
@@ -1220,7 +1220,7 @@ index fcf85047d89d5c55df78ab2a6d81cb6da254ecd7..8ad1c6f8147cfbd4677252a0d76f1477
Visibility visibility = this.currentSection.getStatus();
if (!this.currentSection.remove(this.entity)) {
-@@ -512,6 +517,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
+@@ -524,6 +529,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
if (!this.currentSection.remove(this.entity)) {
PersistentEntitySectionManager.LOGGER.warn("Entity {} wasn't found in section {} (destroying due to {})", new Object[]{this.entity, SectionPos.of(this.currentSectionKey), reason});
}
diff --git a/patches/server/0736-Do-not-copy-visible-chunks.patch b/patches/server/0736-Do-not-copy-visible-chunks.patch
deleted file mode 100644
index 1b2f6fcee8..0000000000
--- a/patches/server/0736-Do-not-copy-visible-chunks.patch
+++ /dev/null
@@ -1,238 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Spottedleaf <[email protected]>
-Date: Sun, 21 Mar 2021 11:22:10 -0700
-Subject: [PATCH] Do not copy visible chunks
-
-For servers with a lot of chunk holders, copying for each
-tickDistanceManager call can take up quite a bit in
-the function. I saw approximately 1/3rd of the function
-on the copy.
-
-diff --git a/src/main/java/io/papermc/paper/command/subcommands/ChunkDebugCommand.java b/src/main/java/io/papermc/paper/command/subcommands/ChunkDebugCommand.java
-index 029ad37df71e74d9feb57e4b31b3602e55d49113..4b367982fae4662c326aa247824e9c4185896de1 100644
---- a/src/main/java/io/papermc/paper/command/subcommands/ChunkDebugCommand.java
-+++ b/src/main/java/io/papermc/paper/command/subcommands/ChunkDebugCommand.java
-@@ -90,7 +90,7 @@ public final class ChunkDebugCommand implements PaperSubcommand {
- int ticking = 0;
- int entityTicking = 0;
-
-- for (final ChunkHolder chunk : world.getChunkSource().chunkMap.updatingChunkMap.values()) {
-+ for (final ChunkHolder chunk : world.getChunkSource().chunkMap.updatingChunks.getUpdatingMap().values()) { // Paper - change updating chunks map
- if (chunk.getFullChunkNowUnchecked() == null) {
- continue;
- }
-diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java
-index 613988c9ea892ab15516e1c8b4f376d52415ae34..1eb71004a19866590a3d27fa6e72842934989177 100644
---- a/src/main/java/net/minecraft/server/MCUtil.java
-+++ b/src/main/java/net/minecraft/server/MCUtil.java
-@@ -625,7 +625,7 @@ public final class MCUtil {
-
- ServerLevel world = ((org.bukkit.craftbukkit.CraftWorld)bukkitWorld).getHandle();
- ChunkMap chunkMap = world.getChunkSource().chunkMap;
-- Long2ObjectLinkedOpenHashMap<ChunkHolder> visibleChunks = chunkMap.visibleChunkMap;
-+ Long2ObjectLinkedOpenHashMap<ChunkHolder> visibleChunks = chunkMap.updatingChunks.getVisibleMap(); // Paper
- DistanceManager chunkMapDistance = chunkMap.distanceManager;
- List<ChunkHolder> allChunks = new ArrayList<>(visibleChunks.values());
- List<ServerPlayer> players = world.players;
-diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
-index 1bbb15354e457a6056d380f9ef318a4661f460e3..b3dc2e71230304ab42b9dd935025f0bd3117bd01 100644
---- a/src/main/java/net/minecraft/server/level/ChunkMap.java
-+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
-@@ -123,9 +123,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
- private static final int MIN_VIEW_DISTANCE = 3;
- public static final int MAX_VIEW_DISTANCE = 33;
- public static final int MAX_CHUNK_DISTANCE = 33 + ChunkStatus.maxDistance();
-+ // Paper start - Don't copy
-+ public final com.destroystokyo.paper.util.map.QueuedChangesMapLong2Object<ChunkHolder> updatingChunks = new com.destroystokyo.paper.util.map.QueuedChangesMapLong2Object<>();
-+ // Paper end - Don't copy
- public static final int FORCED_TICKET_LEVEL = 31;
-- public final Long2ObjectLinkedOpenHashMap<ChunkHolder> updatingChunkMap = new Long2ObjectLinkedOpenHashMap();
-- public volatile Long2ObjectLinkedOpenHashMap<ChunkHolder> visibleChunkMap;
-+ // Paper - Don't copy
- private final Long2ObjectLinkedOpenHashMap<ChunkHolder> pendingUnloads;
- public final LongSet entitiesInLevel;
- public final ServerLevel level;
-@@ -318,7 +320,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
- boolean unloadingPlayerChunk = false; // Paper - do not allow ticket level changes while unloading chunks
- public ChunkMap(ServerLevel world, LevelStorageSource.LevelStorageAccess session, DataFixer dataFixer, StructureTemplateManager structureTemplateManager, Executor executor, BlockableEventLoop<Runnable> mainThreadExecutor, LightChunkGetter chunkProvider, ChunkGenerator chunkGenerator, ChunkProgressListener worldGenerationProgressListener, ChunkStatusUpdateListener chunkStatusChangeListener, Supplier<DimensionDataStorage> persistentStateManagerFactory, int viewDistance, boolean dsync) {
- super(session.getDimensionPath(world.dimension()).resolve("region"), dataFixer, dsync);
-- this.visibleChunkMap = this.updatingChunkMap.clone();
-+ // Paper - don't copy
- this.pendingUnloads = new Long2ObjectLinkedOpenHashMap();
- this.entitiesInLevel = new LongOpenHashSet();
- this.toDrop = new LongOpenHashSet();
-@@ -559,12 +561,17 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
-
- @Nullable
- public ChunkHolder getUpdatingChunkIfPresent(long pos) {
-- return (ChunkHolder) this.updatingChunkMap.get(pos);
-+ return this.updatingChunks.getUpdating(pos); // Paper - Don't copy
- }
-
- @Nullable
- public ChunkHolder getVisibleChunkIfPresent(long pos) {
-- return (ChunkHolder) this.visibleChunkMap.get(pos);
-+ // Paper start - Don't copy
-+ if (Thread.currentThread() == this.level.thread) {
-+ return this.updatingChunks.getVisible(pos);
-+ }
-+ return this.updatingChunks.getVisibleAsync(pos);
-+ // Paper end - Don't copy
- }
-
- protected IntSupplier getChunkQueueLevel(long pos) {
-@@ -704,9 +711,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
- };
-
- stringbuilder.append("Updating:").append(System.lineSeparator());
-- this.updatingChunkMap.values().forEach(consumer);
-+ this.updatingChunks.getUpdatingValuesCopy().forEach(consumer); // Paper
- stringbuilder.append("Visible:").append(System.lineSeparator());
-- this.visibleChunkMap.values().forEach(consumer);
-+ this.updatingChunks.getVisibleValuesCopy().forEach(consumer); // Paper
- CrashReport crashreport = CrashReport.forThrowable(exception, "Chunk loading");
- CrashReportCategory crashreportsystemdetails = crashreport.addCategory("Chunk loading");
-
-@@ -757,7 +764,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
- // Paper end
- }
-
-- this.updatingChunkMap.put(pos, holder);
-+ this.updatingChunks.queueUpdate(pos, holder); // Paper - Don't copy
- this.modified = true;
- }
-
-@@ -837,7 +844,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
-
- protected void saveAllChunks(boolean flush) {
- if (flush) {
-- List<ChunkHolder> list = (List) this.visibleChunkMap.values().stream().filter(ChunkHolder::wasAccessibleSinceLastSave).peek(ChunkHolder::refreshAccessibility).collect(Collectors.toList());
-+ List<ChunkHolder> list = (List) this.updatingChunks.getVisibleValuesCopy().stream().filter(ChunkHolder::wasAccessibleSinceLastSave).peek(ChunkHolder::refreshAccessibility).collect(Collectors.toList()); // Paper
- MutableBoolean mutableboolean = new MutableBoolean();
-
- do {
-@@ -868,7 +875,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
- //this.flushWorker(); // Paper - nuke IOWorker
- this.level.asyncChunkTaskManager.flush(); // Paper - flush to preserve behavior compat with pre-async behaviour
- } else {
-- this.visibleChunkMap.values().forEach(this::saveChunkIfNeeded);
-+ this.updatingChunks.getVisibleValuesCopy().forEach(this::saveChunkIfNeeded); // Paper
- }
-
- }
-@@ -891,14 +898,14 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
- }
-
- public boolean hasWork() {
-- return this.lightEngine.hasLightWork() || !this.pendingUnloads.isEmpty() || !this.updatingChunkMap.isEmpty() || this.poiManager.hasWork() || !this.toDrop.isEmpty() || !this.unloadQueue.isEmpty() || this.queueSorter.hasWork() || this.distanceManager.hasTickets();
-+ return this.lightEngine.hasLightWork() || !this.pendingUnloads.isEmpty() || !this.updatingChunks.getUpdatingValuesCopy().isEmpty() || this.poiManager.hasWork() || !this.toDrop.isEmpty() || !this.unloadQueue.isEmpty() || this.queueSorter.hasWork() || this.distanceManager.hasTickets(); // Paper
- }
-
- private void processUnloads(BooleanSupplier shouldKeepTicking) {
- LongIterator longiterator = this.toDrop.iterator();
- for (int i = 0; longiterator.hasNext() && (shouldKeepTicking.getAsBoolean() || i < 200 || this.toDrop.size() > 2000); longiterator.remove()) {
- long j = longiterator.nextLong();
-- ChunkHolder playerchunk = (ChunkHolder) this.updatingChunkMap.remove(j);
-+ ChunkHolder playerchunk = this.updatingChunks.queueRemove(j); // Paper - Don't copy
-
- if (playerchunk != null) {
- playerchunk.onChunkRemove(); // Paper
-@@ -993,7 +1000,12 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
- if (!this.modified) {
- return false;
- } else {
-- this.visibleChunkMap = this.updatingChunkMap.clone();
-+ // Paper start - Don't copy
-+ synchronized (this.updatingChunks) {
-+ this.updatingChunks.performUpdates();
-+ }
-+ // Paper end - Don't copy
-+
- this.modified = false;
- return true;
- }
-@@ -1493,7 +1505,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
-
- this.viewDistance = j;
- this.distanceManager.updatePlayerTickets(this.viewDistance + 1);
-- ObjectIterator objectiterator = this.updatingChunkMap.values().iterator();
-+ Iterator objectiterator = this.updatingChunks.getVisibleValuesCopy().iterator(); // Paper
-
- while (objectiterator.hasNext()) {
- ChunkHolder playerchunk = (ChunkHolder) objectiterator.next();
-@@ -1536,7 +1548,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
- }
-
- public int size() {
-- return this.visibleChunkMap.size();
-+ return this.updatingChunks.getVisibleMap().size(); // Paper - Don't copy
- }
-
- public DistanceManager getDistanceManager() {
-@@ -1544,13 +1556,13 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
- }
-
- protected Iterable<ChunkHolder> getChunks() {
-- return Iterables.unmodifiableIterable(this.visibleChunkMap.values());
-+ return Iterables.unmodifiableIterable(this.updatingChunks.getVisibleValuesCopy()); // Paper
- }
-
- void dumpChunks(Writer writer) throws IOException {
- CsvOutput csvwriter = CsvOutput.builder().addColumn("x").addColumn("z").addColumn("level").addColumn("in_memory").addColumn("status").addColumn("full_status").addColumn("accessible_ready").addColumn("ticking_ready").addColumn("entity_ticking_ready").addColumn("ticket").addColumn("spawning").addColumn("block_entity_count").addColumn("ticking_ticket").addColumn("ticking_level").addColumn("block_ticks").addColumn("fluid_ticks").build(writer);
- TickingTracker tickingtracker = this.distanceManager.tickingTracker();
-- ObjectBidirectionalIterator objectbidirectionaliterator = this.visibleChunkMap.long2ObjectEntrySet().iterator();
-+ ObjectBidirectionalIterator objectbidirectionaliterator = this.updatingChunks.getVisibleMap().clone().long2ObjectEntrySet().fastIterator(); // Paper
-
- while (objectbidirectionaliterator.hasNext()) {
- Entry<ChunkHolder> entry = (Entry) objectbidirectionaliterator.next();
-diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-index 21bf39ef5b20ecc989881b07c4e6b90c68540afd..beee040abf846492cefabe985c5286b00fc6bc63 100644
---- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-@@ -167,7 +167,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
- @Override
- public int getTileEntityCount() {
- // We don't use the full world tile entity list, so we must iterate chunks
-- Long2ObjectLinkedOpenHashMap<ChunkHolder> chunks = world.getChunkSource().chunkMap.visibleChunkMap;
-+ Long2ObjectLinkedOpenHashMap<ChunkHolder> chunks = world.getChunkSource().chunkMap.updatingChunks.getVisibleMap(); // Paper - change updating chunks map
- int size = 0;
- for (ChunkHolder playerchunk : chunks.values()) {
- net.minecraft.world.level.chunk.LevelChunk chunk = playerchunk.getTickingChunk();
-@@ -188,7 +188,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
- public int getChunkCount() {
- int ret = 0;
-
-- for (ChunkHolder chunkHolder : world.getChunkSource().chunkMap.visibleChunkMap.values()) {
-+ for (ChunkHolder chunkHolder : world.getChunkSource().chunkMap.updatingChunks.getVisibleMap().values()) { // Paper - change updating chunks map
- if (chunkHolder.getTickingChunk() != null) {
- ++ret;
- }
-@@ -345,7 +345,18 @@ public class CraftWorld extends CraftRegionAccessor implements World {
-
- @Override
- public Chunk[] getLoadedChunks() {
-- Long2ObjectLinkedOpenHashMap<ChunkHolder> chunks = this.world.getChunkSource().chunkMap.visibleChunkMap;
-+ // Paper start
-+ if (Thread.currentThread() != world.getLevel().thread) {
-+ // Paper start - change updating chunks map
-+ Long2ObjectLinkedOpenHashMap<ChunkHolder> chunks;
-+ synchronized (world.getChunkSource().chunkMap.updatingChunks) {
-+ chunks = world.getChunkSource().chunkMap.updatingChunks.getVisibleMap().clone();
-+ }
-+ return chunks.values().stream().map(ChunkHolder::getFullChunkNow).filter(Objects::nonNull).map(net.minecraft.world.level.chunk.LevelChunk::getBukkitChunk).toArray(Chunk[]::new);
-+ // Paper end - change updating chunks map
-+ }
-+ // Paper end
-+ Long2ObjectLinkedOpenHashMap<ChunkHolder> chunks = this.world.getChunkSource().chunkMap.updatingChunks.getVisibleMap(); // Paper - change updating chunks map
- return chunks.values().stream().map(ChunkHolder::getFullChunkNow).filter(Objects::nonNull).map(net.minecraft.world.level.chunk.LevelChunk::getBukkitChunk).toArray(Chunk[]::new);
- }
-
-@@ -421,7 +432,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
-
- @Override
- public boolean refreshChunk(int x, int z) {
-- ChunkHolder playerChunk = this.world.getChunkSource().chunkMap.visibleChunkMap.get(ChunkPos.asLong(x, z));
-+ ChunkHolder playerChunk = this.world.getChunkSource().chunkMap.updatingChunks.getVisibleMap().get(ChunkPos.asLong(x, z));
- if (playerChunk == null) return false;
-
- playerChunk.getTickingChunkFuture().thenAccept(either -> {
diff --git a/patches/server/0734-Optimise-chunk-tick-iteration.patch b/patches/server/0736-Optimise-chunk-tick-iteration.patch
index 3789453481..13c8c24128 100644
--- a/patches/server/0734-Optimise-chunk-tick-iteration.patch
+++ b/patches/server/0736-Optimise-chunk-tick-iteration.patch
@@ -6,13 +6,13 @@ 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/level/ChunkHolder.java b/src/main/java/net/minecraft/server/level/ChunkHolder.java
-index b75b3c4d274252a3a5c53059b9702728eeada389..8bea90cb57f38f33e8b3162e24e353993a98ebbf 100644
+index a2b5f6457b08e4e02544dc71fbf383b5a67a2d69..538f21e6bc29c0307441fe4899dc7f600d2d1a04 100644
--- a/src/main/java/net/minecraft/server/level/ChunkHolder.java
+++ b/src/main/java/net/minecraft/server/level/ChunkHolder.java
-@@ -86,11 +86,21 @@ public class ChunkHolder {
- long key = net.minecraft.server.MCUtil.getCoordinateKey(this.pos);
+@@ -84,6 +84,11 @@ public class ChunkHolder {
this.playersInMobSpawnRange = this.chunkMap.playerMobSpawnMap.getObjectsInRange(key);
this.playersInChunkTickRange = this.chunkMap.playerChunkTickRangeMap.getObjectsInRange(key);
+ // Paper end - optimise anyPlayerCloseEnoughForSpawning
+ // Paper start - optimise chunk tick iteration
+ if (this.needsBroadcastChanges()) {
+ this.chunkMap.needsChangeBroadcasting.add(this);
@@ -20,18 +20,20 @@ index b75b3c4d274252a3a5c53059b9702728eeada389..8bea90cb57f38f33e8b3162e24e35399
+ // Paper end - optimise chunk tick iteration
}
- void onChunkRemove() {
+ public void onChunkRemove() {
+@@ -91,6 +96,11 @@ public class ChunkHolder {
this.playersInMobSpawnRange = null;
this.playersInChunkTickRange = null;
+ // Paper end - optimise anyPlayerCloseEnoughForSpawning
+ // Paper start - optimise chunk tick iteration
+ if (this.needsBroadcastChanges()) {
+ this.chunkMap.needsChangeBroadcasting.remove(this);
+ }
+ // Paper end - optimise chunk tick iteration
}
- // Paper end - optimise anyPlayerCloseEnoughForSpawning
- long lastAutoSaveTime; // Paper - incremental autosave
-@@ -253,7 +263,7 @@ public class ChunkHolder {
+ // Paper end
+
+@@ -258,7 +268,7 @@ public class ChunkHolder {
if (i < 0 || i >= this.changedBlocksPerSection.length) return; // CraftBukkit - SPIGOT-6086, SPIGOT-6296
if (this.changedBlocksPerSection[i] == null) {
@@ -40,7 +42,7 @@ index b75b3c4d274252a3a5c53059b9702728eeada389..8bea90cb57f38f33e8b3162e24e35399
this.changedBlocksPerSection[i] = new ShortOpenHashSet();
}
-@@ -276,6 +286,7 @@ public class ChunkHolder {
+@@ -281,6 +291,7 @@ public class ChunkHolder {
int k = this.lightEngine.getMaxLightSection();
if (y >= j && y <= k) {
@@ -48,7 +50,7 @@ index b75b3c4d274252a3a5c53059b9702728eeada389..8bea90cb57f38f33e8b3162e24e35399
int l = y - j;
if (lightType == LightLayer.SKY) {
-@@ -290,8 +301,19 @@ public class ChunkHolder {
+@@ -295,8 +306,19 @@ public class ChunkHolder {
}
}
@@ -70,10 +72,10 @@ index b75b3c4d274252a3a5c53059b9702728eeada389..8bea90cb57f38f33e8b3162e24e35399
int i = 0;
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
-index ae0d7295c88005749f13dd230136f4a39d0a578e..1bbb15354e457a6056d380f9ef318a4661f460e3 100644
+index b34c90497a5492c289839ba74df9f2f27e29370e..e811c7d617b8c9cc684bc0a58a98d5ecfe11db02 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
-@@ -160,6 +160,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -162,6 +162,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
private final Queue<Runnable> unloadQueue;
int viewDistance;
public final com.destroystokyo.paper.util.misc.PlayerAreaMap playerMobDistanceMap; // Paper
@@ -82,7 +84,7 @@ index ae0d7295c88005749f13dd230136f4a39d0a578e..1bbb15354e457a6056d380f9ef318a46
// CraftBukkit start - recursion-safe executor for Chunk loadCallback() and unloadCallback()
public final CallbackExecutor callbackExecutor = new CallbackExecutor();
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
-index ce88da358c8a89564a911e6c818e906e845006ff..438406936633b9c67d21b26527c3d1654118c744 100644
+index 9f7ec687e6cf971bb9699e9f4ad7ebe37a3ef882..e585d0047f1dbafeb2bcacf19bd38f3d4b9ab53e 100644
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
@@ -47,6 +47,7 @@ import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemp
@@ -93,7 +95,7 @@ index ce88da358c8a89564a911e6c818e906e845006ff..438406936633b9c67d21b26527c3d165
public class ServerChunkCache extends ChunkSource {
-@@ -987,34 +988,42 @@ public class ServerChunkCache extends ChunkSource {
+@@ -808,34 +809,42 @@ public class ServerChunkCache extends ChunkSource {
this.lastSpawnState = spawnercreature_d;
gameprofilerfiller.popPush("filteringLoadedChunks");
@@ -152,24 +154,24 @@ index ce88da358c8a89564a911e6c818e906e845006ff..438406936633b9c67d21b26527c3d165
NaturalSpawner.spawnForChunk(this.level, chunk1, spawnercreature_d, this.spawnFriendlies, this.spawnEnemies, flag1);
}
-@@ -1022,7 +1031,16 @@ public class ServerChunkCache extends ChunkSource {
+@@ -843,7 +852,16 @@ public class ServerChunkCache extends ChunkSource {
this.level.tickChunk(chunk1, k);
}
}
+ // Paper start - optimise chunk tick iteration
+ }
- }
++ }
+
+ } finally {
+ if (iterator1 instanceof io.papermc.paper.util.maplist.IteratorSafeOrderedReferenceSet.Iterator safeIterator) {
+ safeIterator.finishedIterating();
+ }
-+ }
+ }
+ // Paper end - optimise chunk tick iteration
this.level.timings.chunkTicks.stopTiming(); // Paper
gameprofilerfiller.popPush("customSpawners");
if (flag2) {
-@@ -1030,15 +1048,24 @@ public class ServerChunkCache extends ChunkSource {
+@@ -851,15 +869,24 @@ public class ServerChunkCache extends ChunkSource {
this.level.tickCustomSpawners(this.spawnEnemies, this.spawnFriendlies);
} // Paper - timings
}
diff --git a/patches/server/0735-Execute-chunk-tasks-mid-tick.patch b/patches/server/0737-Execute-chunk-tasks-mid-tick.patch
index 7081da1b7a..90d5f94f2f 100644
--- a/patches/server/0735-Execute-chunk-tasks-mid-tick.patch
+++ b/patches/server/0737-Execute-chunk-tasks-mid-tick.patch
@@ -106,10 +106,10 @@ index 98fe4165d291b47a39ce741884353c87dd0a4789..99073ea2757cd1c15b098d7cfaf86817
+ // Paper end - execute chunk tasks mid tick
}
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
-index 438406936633b9c67d21b26527c3d1654118c744..2de322ffc2eedae9efe39f9b771c447dd76f26fb 100644
+index e585d0047f1dbafeb2bcacf19bd38f3d4b9ab53e..5ef0ddad4a129b53e3102f177f31f28d5f4cf455 100644
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
-@@ -1012,6 +1012,7 @@ public class ServerChunkCache extends ChunkSource {
+@@ -833,6 +833,7 @@ public class ServerChunkCache extends ChunkSource {
iterator1 = shuffled.iterator();
}
@@ -117,7 +117,7 @@ index 438406936633b9c67d21b26527c3d1654118c744..2de322ffc2eedae9efe39f9b771c447d
try {
while (iterator1.hasNext()) {
LevelChunk chunk1 = iterator1.next();
-@@ -1029,6 +1030,7 @@ public class ServerChunkCache extends ChunkSource {
+@@ -850,6 +851,7 @@ public class ServerChunkCache extends ChunkSource {
if (this.level.shouldTickBlocksAt(chunkcoordintpair.toLong())) {
this.level.tickChunk(chunk1, k);
@@ -126,7 +126,7 @@ index 438406936633b9c67d21b26527c3d1654118c744..2de322ffc2eedae9efe39f9b771c447d
}
// Paper start - optimise chunk tick iteration
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index f3aa1276f0689996ce7827c9300c141dd95582cc..6eca2940cedc5c4fd73906cc4f5657c78d646a10 100644
+index 29b80d074600fa7e20b05d1fe70ac12969b954a4..7324f2ad437a15c42f84ba2deeb58861c0552209 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -212,6 +212,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
@@ -137,7 +137,7 @@ index f3aa1276f0689996ce7827c9300c141dd95582cc..6eca2940cedc5c4fd73906cc4f5657c7
// CraftBukkit start
public final LevelStorageSource.LevelStorageAccess convertable;
-@@ -989,6 +990,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -991,6 +992,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
if (fluid1.is(fluid)) {
fluid1.tick(this, pos);
}
@@ -145,7 +145,7 @@ index f3aa1276f0689996ce7827c9300c141dd95582cc..6eca2940cedc5c4fd73906cc4f5657c7
}
-@@ -998,6 +1000,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -1000,6 +1002,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
if (iblockdata.is(block)) {
iblockdata.tick(this, pos, this.random);
}
diff --git a/patches/server/0737-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch b/patches/server/0738-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch
index 06d2ade2a6..c448b0249c 100644
--- a/patches/server/0737-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch
+++ b/patches/server/0738-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch
@@ -685,7 +685,7 @@ index 861a25a15f1aab20e3245b6d5cdad5d23bdfd6d0..8ff8855c5267379b3a5f5d8baa4a275f
return bytebuffer;
}
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
-index 0d96d1c0b66c57c680759f3567ef1b0c326d8cfa..6986a170f37f70e8eb89d79d5d2615a06a5e0f0c 100644
+index 666286f94f09299f95538ef2f19b588eb74d9dda..f38ec8914e1953091ab65aa3aaefc886d3eede8a 100644
--- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
@@ -26,7 +26,15 @@ public class RegionFileStorage implements AutoCloseable {
diff --git a/patches/server/0738-Custom-table-implementation-for-blockstate-state-loo.patch b/patches/server/0739-Custom-table-implementation-for-blockstate-state-loo.patch
index 6cf6b743b6..6cf6b743b6 100644
--- a/patches/server/0738-Custom-table-implementation-for-blockstate-state-loo.patch
+++ b/patches/server/0739-Custom-table-implementation-for-blockstate-state-loo.patch
diff --git a/patches/server/0739-Detail-more-information-in-watchdog-dumps.patch b/patches/server/0740-Detail-more-information-in-watchdog-dumps.patch
index 73d66a556b..7b40f83dd9 100644
--- a/patches/server/0739-Detail-more-information-in-watchdog-dumps.patch
+++ b/patches/server/0740-Detail-more-information-in-watchdog-dumps.patch
@@ -78,10 +78,10 @@ index acfa1907bfc9c29d261cfccc00d65bad9ad1a002..d6f3869f5725c7f081efb7f486f74dbb
});
throw RunningOnDifferentThreadException.RUNNING_ON_DIFFERENT_THREAD;
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index 6eca2940cedc5c4fd73906cc4f5657c78d646a10..673da1feb2960a6d247265237eae480d34f58056 100644
+index 7324f2ad437a15c42f84ba2deeb58861c0552209..92aafd475d58d1ef2e2736d9363c4b1010724fd7 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
-@@ -1004,7 +1004,26 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -1006,7 +1006,26 @@ public class ServerLevel extends Level implements WorldGenLevel {
}
@@ -108,7 +108,7 @@ index 6eca2940cedc5c4fd73906cc4f5657c78d646a10..673da1feb2960a6d247265237eae480d
++TimingHistory.entityTicks; // Paper - timings
// Spigot start
co.aikar.timings.Timing timer; // Paper
-@@ -1044,7 +1063,13 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -1046,7 +1065,13 @@ public class ServerLevel extends Level implements WorldGenLevel {
this.tickPassenger(entity, entity1);
}
// } finally { timer.stopTiming(); } // Paper - timings - move up
diff --git a/patches/server/0740-Manually-inline-methods-in-BlockPosition.patch b/patches/server/0741-Manually-inline-methods-in-BlockPosition.patch
index 0cab0f9b56..0cab0f9b56 100644
--- a/patches/server/0740-Manually-inline-methods-in-BlockPosition.patch
+++ b/patches/server/0741-Manually-inline-methods-in-BlockPosition.patch
diff --git a/patches/server/0741-Distance-manager-tick-timings.patch b/patches/server/0742-Distance-manager-tick-timings.patch
index 98a316c64e..411ac81671 100644
--- a/patches/server/0741-Distance-manager-tick-timings.patch
+++ b/patches/server/0742-Distance-manager-tick-timings.patch
@@ -19,10 +19,10 @@ index 5ec241d49ff5e3a161a39006f05823a5de847c5e..435b3b6d05e00803386d123c66f961c9
public static final Timing midTickChunkTasks = Timings.ofSafe("Mid Tick Chunk Tasks");
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
-index 2de322ffc2eedae9efe39f9b771c447dd76f26fb..7524d9cf7184b345cbd7f0bd1d85601b75c29087 100644
+index 5ef0ddad4a129b53e3102f177f31f28d5f4cf455..5aa5e951f7827e81d370825f0ac8afd78f482955 100644
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
-@@ -824,6 +824,7 @@ public class ServerChunkCache extends ChunkSource {
+@@ -645,6 +645,7 @@ public class ServerChunkCache extends ChunkSource {
public boolean runDistanceManagerUpdates() {
if (distanceManager.delayDistanceManagerTick) return false; // Paper - Chunk priority
if (this.chunkMap.unloadingPlayerChunk) { LOGGER.error("Cannot tick distance manager while unloading playerchunks", new Throwable()); throw new IllegalStateException("Cannot tick distance manager while unloading playerchunks"); } // Paper
@@ -30,7 +30,7 @@ index 2de322ffc2eedae9efe39f9b771c447dd76f26fb..7524d9cf7184b345cbd7f0bd1d85601b
boolean flag = this.distanceManager.runAllUpdates(this.chunkMap);
boolean flag1 = this.chunkMap.promoteChunkMap();
-@@ -833,6 +834,7 @@ public class ServerChunkCache extends ChunkSource {
+@@ -654,6 +655,7 @@ public class ServerChunkCache extends ChunkSource {
this.clearCache();
return true;
}
diff --git a/patches/server/0742-Name-craft-scheduler-threads-according-to-the-plugin.patch b/patches/server/0743-Name-craft-scheduler-threads-according-to-the-plugin.patch
index 7d081ee195..7d081ee195 100644
--- a/patches/server/0742-Name-craft-scheduler-threads-according-to-the-plugin.patch
+++ b/patches/server/0743-Name-craft-scheduler-threads-according-to-the-plugin.patch
diff --git a/patches/server/0743-Make-sure-inlined-getChunkAt-has-inlined-logic-for-l.patch b/patches/server/0744-Make-sure-inlined-getChunkAt-has-inlined-logic-for-l.patch
index 300dfa8887..300dfa8887 100644
--- a/patches/server/0743-Make-sure-inlined-getChunkAt-has-inlined-logic-for-l.patch
+++ b/patches/server/0744-Make-sure-inlined-getChunkAt-has-inlined-logic-for-l.patch
diff --git a/patches/server/0744-Add-packet-limiter-config.patch b/patches/server/0745-Add-packet-limiter-config.patch
index 8aa45e5f93..8aa45e5f93 100644
--- a/patches/server/0744-Add-packet-limiter-config.patch
+++ b/patches/server/0745-Add-packet-limiter-config.patch
diff --git a/patches/server/0745-Use-correct-LevelStem-registry-when-loading-default-.patch b/patches/server/0746-Use-correct-LevelStem-registry-when-loading-default-.patch
index 82aca1adfa..acaf871233 100644
--- a/patches/server/0745-Use-correct-LevelStem-registry-when-loading-default-.patch
+++ b/patches/server/0746-Use-correct-LevelStem-registry-when-loading-default-.patch
@@ -24,7 +24,7 @@ index 8da1226a6c293abb038d10c7921a77ed71ad06cc..f958f0ae738a6fb26400e17e54c8d69e
} else {
Holder<E> holder = registry.getOrCreateHolderOrThrow(entryKey);
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
-index 2d94390e3b9fa3afd2471cc691d59de0f470b46c..68c0bb1d493b3de3c3e80018a1655ec968b0316a 100644
+index 99073ea2757cd1c15b098d7cfaf8681702f04a19..857af8ed37c10723d6cd81d7f3c2ba6169021050 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -553,7 +553,14 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
diff --git a/patches/server/0746-Don-t-read-neighbour-chunk-data-off-disk-when-conver.patch b/patches/server/0747-Don-t-read-neighbour-chunk-data-off-disk-when-conver.patch
index 7f656dff77..7f656dff77 100644
--- a/patches/server/0746-Don-t-read-neighbour-chunk-data-off-disk-when-conver.patch
+++ b/patches/server/0747-Don-t-read-neighbour-chunk-data-off-disk-when-conver.patch
diff --git a/patches/server/0747-Consolidate-flush-calls-for-entity-tracker-packets.patch b/patches/server/0748-Consolidate-flush-calls-for-entity-tracker-packets.patch
index 17c273d2c0..8ff310e939 100644
--- a/patches/server/0747-Consolidate-flush-calls-for-entity-tracker-packets.patch
+++ b/patches/server/0748-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/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
-index 7524d9cf7184b345cbd7f0bd1d85601b75c29087..96a232f22b1c270b91635ce9c7c6cacc63b026cc 100644
+index 5aa5e951f7827e81d370825f0ac8afd78f482955..3b549ac6d07484a09dc6521cb4f3ab3b3cc979e9 100644
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
-@@ -1070,7 +1070,24 @@ public class ServerChunkCache extends ChunkSource {
+@@ -891,7 +891,24 @@ public class ServerChunkCache extends ChunkSource {
this.level.timings.broadcastChunkUpdates.stopTiming(); // Paper - timing
gameprofilerfiller.pop();
// Paper end - use set of chunks requiring updates, rather than iterating every single one loaded
diff --git a/patches/server/0748-Don-t-lookup-fluid-state-when-raytracing.patch b/patches/server/0749-Don-t-lookup-fluid-state-when-raytracing.patch
index eef7de0e32..eef7de0e32 100644
--- a/patches/server/0748-Don-t-lookup-fluid-state-when-raytracing.patch
+++ b/patches/server/0749-Don-t-lookup-fluid-state-when-raytracing.patch
diff --git a/patches/server/0749-Time-scoreboard-search.patch b/patches/server/0750-Time-scoreboard-search.patch
index bcff6d3469..d1b1fd45ef 100644
--- a/patches/server/0749-Time-scoreboard-search.patch
+++ b/patches/server/0750-Time-scoreboard-search.patch
@@ -19,7 +19,7 @@ index 435b3b6d05e00803386d123c66f961c97da83d40..9da5a6086323ff4c4fd62a035fa8f7ef
public static final Timing midTickChunkTasks = Timings.ofSafe("Mid Tick Chunk Tasks");
diff --git a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java
-index 60d5564b5eb9f91db6b02bd4fb037a11fc6dfeb3..c74ac9cf5db4d8adfe781cf066258011da469717 100644
+index 39e19bea16419b9cbe53016084b8bbf014dcb056..138407c2d4b0bc55ddb9aac5d2aa3edadda090fb 100644
--- a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java
+++ b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java
@@ -113,9 +113,18 @@ public final class CraftScoreboardManager implements ScoreboardManager {
diff --git a/patches/server/0750-Send-full-pos-packets-for-hard-colliding-entities.patch b/patches/server/0751-Send-full-pos-packets-for-hard-colliding-entities.patch
index b63f55bd81..b63f55bd81 100644
--- a/patches/server/0750-Send-full-pos-packets-for-hard-colliding-entities.patch
+++ b/patches/server/0751-Send-full-pos-packets-for-hard-colliding-entities.patch
diff --git a/patches/server/0751-Do-not-run-raytrace-logic-for-AIR.patch b/patches/server/0752-Do-not-run-raytrace-logic-for-AIR.patch
index baedf55a9d..baedf55a9d 100644
--- a/patches/server/0751-Do-not-run-raytrace-logic-for-AIR.patch
+++ b/patches/server/0752-Do-not-run-raytrace-logic-for-AIR.patch
diff --git a/patches/server/0752-Oprimise-map-impl-for-tracked-players.patch b/patches/server/0753-Oprimise-map-impl-for-tracked-players.patch
index a7f5f938d1..e1ee820045 100644
--- a/patches/server/0752-Oprimise-map-impl-for-tracked-players.patch
+++ b/patches/server/0753-Oprimise-map-impl-for-tracked-players.patch
@@ -7,7 +7,7 @@ Reference2BooleanOpenHashMap is going to have
better lookups than HashMap.
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
-index b3dc2e71230304ab42b9dd935025f0bd3117bd01..5507f6982bfc02f648a7aa4e4860378fc442cf34 100644
+index e811c7d617b8c9cc684bc0a58a98d5ecfe11db02..f47e2d4a7343f3e3ee68f36688720cedc58861dc 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -110,6 +110,7 @@ import org.slf4j.Logger;
@@ -18,7 +18,7 @@ index b3dc2e71230304ab42b9dd935025f0bd3117bd01..5507f6982bfc02f648a7aa4e4860378f
public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider {
-@@ -2200,7 +2201,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -2212,7 +2213,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
final Entity entity;
private final int range;
SectionPos lastSectionPos;
diff --git a/patches/server/0753-Optimise-BlockSoil-nearby-water-lookup.patch b/patches/server/0754-Optimise-BlockSoil-nearby-water-lookup.patch
index bb523f58c5..bb523f58c5 100644
--- a/patches/server/0753-Optimise-BlockSoil-nearby-water-lookup.patch
+++ b/patches/server/0754-Optimise-BlockSoil-nearby-water-lookup.patch
diff --git a/patches/server/0754-Allow-removal-addition-of-entities-to-entity-ticklis.patch b/patches/server/0755-Allow-removal-addition-of-entities-to-entity-ticklis.patch
index bf79d6270e..bf79d6270e 100644
--- a/patches/server/0754-Allow-removal-addition-of-entities-to-entity-ticklis.patch
+++ b/patches/server/0755-Allow-removal-addition-of-entities-to-entity-ticklis.patch
diff --git a/patches/server/0755-Optimise-random-block-ticking.patch b/patches/server/0756-Optimise-random-block-ticking.patch
index 8773a15856..c824cd4fdc 100644
--- a/patches/server/0755-Optimise-random-block-ticking.patch
+++ b/patches/server/0756-Optimise-random-block-ticking.patch
@@ -90,10 +90,10 @@ index 0000000000000000000000000000000000000000..7d93652c1abbb6aee6eb7c26cf35d4d0
+ }
+}
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index 673da1feb2960a6d247265237eae480d34f58056..82e6a535ff86df7c5fa076d64f09aba4a9231fe6 100644
+index 92aafd475d58d1ef2e2736d9363c4b1010724fd7..bcd1b2534af33e7a9d184e0ea4c9c0a4b58dacc8 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
-@@ -668,6 +668,10 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -670,6 +670,10 @@ public class ServerLevel extends Level implements WorldGenLevel {
entityplayer.stopSleepInBed(false, false);
});
}
@@ -104,7 +104,7 @@ index 673da1feb2960a6d247265237eae480d34f58056..82e6a535ff86df7c5fa076d64f09aba4
public void tickChunk(LevelChunk chunk, int randomTickSpeed) {
ChunkPos chunkcoordintpair = chunk.getPos();
-@@ -677,10 +681,10 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -679,10 +683,10 @@ public class ServerLevel extends Level implements WorldGenLevel {
ProfilerFiller gameprofilerfiller = this.getProfiler();
gameprofilerfiller.push("thunder");
@@ -117,7 +117,7 @@ index 673da1feb2960a6d247265237eae480d34f58056..82e6a535ff86df7c5fa076d64f09aba4
if (this.isRainingAt(blockposition)) {
DifficultyInstance difficultydamagescaler = this.getCurrentDifficultyAt(blockposition);
boolean flag1 = this.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && this.random.nextDouble() < (double) difficultydamagescaler.getEffectiveDifficulty() * this.paperConfig().entities.spawning.skeletonHorseThunderSpawnChance.or(0.01D) && !this.getBlockState(blockposition.below()).is(Blocks.LIGHTNING_ROD); // Paper
-@@ -704,64 +708,75 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -706,64 +710,75 @@ public class ServerLevel extends Level implements WorldGenLevel {
gameprofilerfiller.popPush("iceandsnow");
if (!this.paperConfig().environment.disableIceAndSnow && this.random.nextInt(16) == 0) { // Paper - Disable ice and snow
diff --git a/patches/server/0756-Optimise-non-flush-packet-sending.patch b/patches/server/0757-Optimise-non-flush-packet-sending.patch
index 21c35fd4d5..21c35fd4d5 100644
--- a/patches/server/0756-Optimise-non-flush-packet-sending.patch
+++ b/patches/server/0757-Optimise-non-flush-packet-sending.patch
diff --git a/patches/server/0757-Optimise-nearby-player-lookups.patch b/patches/server/0758-Optimise-nearby-player-lookups.patch
index 42d9b5e8a1..539831eea4 100644
--- a/patches/server/0757-Optimise-nearby-player-lookups.patch
+++ b/patches/server/0758-Optimise-nearby-player-lookups.patch
@@ -9,10 +9,10 @@ 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/level/ChunkHolder.java b/src/main/java/net/minecraft/server/level/ChunkHolder.java
-index 8bea90cb57f38f33e8b3162e24e353993a98ebbf..5b4c3ca92dffff876af18db106310cb14e8612b1 100644
+index df6857ebcddc9a7bab6b82b71bfd447508b078b3..be5a742207623d186c5b936c669eb690c30d0719 100644
--- a/src/main/java/net/minecraft/server/level/ChunkHolder.java
+++ b/src/main/java/net/minecraft/server/level/ChunkHolder.java
-@@ -91,6 +91,12 @@ public class ChunkHolder {
+@@ -89,6 +89,12 @@ public class ChunkHolder {
this.chunkMap.needsChangeBroadcasting.add(this);
}
// Paper end - optimise chunk tick iteration
@@ -24,7 +24,7 @@ index 8bea90cb57f38f33e8b3162e24e353993a98ebbf..5b4c3ca92dffff876af18db106310cb1
+ // Paper end - optimise checkDespawn
}
- void onChunkRemove() {
+ public void onChunkRemove() {
@@ -101,6 +107,12 @@ public class ChunkHolder {
this.chunkMap.needsChangeBroadcasting.remove(this);
}
@@ -36,10 +36,10 @@ index 8bea90cb57f38f33e8b3162e24e353993a98ebbf..5b4c3ca92dffff876af18db106310cb1
+ }
+ // Paper end - optimise checkDespawn
}
- // Paper end - optimise anyPlayerCloseEnoughForSpawning
- long lastAutoSaveTime; // Paper - incremental autosave
+ // Paper end
+
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
-index 5507f6982bfc02f648a7aa4e4860378fc442cf34..97ec72dc383a2637c60cfc988bca2a8a86954ffb 100644
+index b6da7ae1827c4009dc8b22745e82890e1bb0b5ef..95c49072e4e90a44873c96af8173d364a5614dff 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -165,6 +165,13 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
@@ -105,10 +105,10 @@ index 5507f6982bfc02f648a7aa4e4860378fc442cf34..97ec72dc383a2637c60cfc988bca2a8a
protected ChunkGenerator generator() {
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index 82e6a535ff86df7c5fa076d64f09aba4a9231fe6..b0c95b0af6d24b9566b82b2df54eae5108b9b48b 100644
+index bcd1b2534af33e7a9d184e0ea4c9c0a4b58dacc8..25149dde919738859f6fb6b2d0405e90d1732f2b 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
-@@ -409,6 +409,84 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -411,6 +411,84 @@ public class ServerLevel extends Level implements WorldGenLevel {
// Paper end
public final ReferenceOpenHashSet<ServerPlayer> pendingLogin = new ReferenceOpenHashSet<>(); // Paper
@@ -193,7 +193,7 @@ index 82e6a535ff86df7c5fa076d64f09aba4a9231fe6..b0c95b0af6d24b9566b82b2df54eae51
// Add env and gen to constructor, IWorldDataServer -> WorldDataServer
public ServerLevel(MinecraftServer minecraftserver, Executor executor, LevelStorageSource.LevelStorageAccess convertable_conversionsession, PrimaryLevelData iworlddataserver, ResourceKey<Level> resourcekey, LevelStem worlddimension, ChunkProgressListener worldloadlistener, boolean flag, long i, List<CustomSpawner> list, boolean flag1, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider) {
// Holder holder = worlddimension.typeHolder(); // CraftBukkit - decompile error
-@@ -511,6 +589,14 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -513,6 +591,14 @@ public class ServerLevel extends Level implements WorldGenLevel {
}
public void tick(BooleanSupplier shouldKeepTicking) {
diff --git a/patches/server/0758-Optimise-WorldServer-notify.patch b/patches/server/0759-Optimise-WorldServer-notify.patch
index 745e6af137..0e414d0146 100644
--- a/patches/server/0758-Optimise-WorldServer-notify.patch
+++ b/patches/server/0759-Optimise-WorldServer-notify.patch
@@ -8,7 +8,7 @@ Instead, only iterate over navigators in the current region that are
eligible for repathing.
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
-index 97ec72dc383a2637c60cfc988bca2a8a86954ffb..236ba4c1950a3cced590f520b5349eede75fd59b 100644
+index 95c49072e4e90a44873c96af8173d364a5614dff..b98a918ed6d2fabda5bb596dcd13e52033473ebe 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -302,15 +302,81 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
@@ -110,10 +110,10 @@ index 97ec72dc383a2637c60cfc988bca2a8a86954ffb..236ba4c1950a3cced590f520b5349eed
}
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index b0c95b0af6d24b9566b82b2df54eae5108b9b48b..bd64c6d0930565785deb999f43cfaa4eaea53195 100644
+index 25149dde919738859f6fb6b2d0405e90d1732f2b..a7a403d34551453a1e0502fe1f7bc139f645d917 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
-@@ -1120,6 +1120,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -1122,6 +1122,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
public void tickNonPassenger(Entity entity) {
// Paper start - log detailed entity tick information
io.papermc.paper.util.TickThread.ensureTickThread("Cannot tick an entity off-main");
@@ -121,7 +121,7 @@ index b0c95b0af6d24b9566b82b2df54eae5108b9b48b..bd64c6d0930565785deb999f43cfaa4e
try {
if (currentlyTickingEntity.get() == null) {
currentlyTickingEntity.lazySet(entity);
-@@ -1637,9 +1638,18 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -1639,9 +1640,18 @@ public class ServerLevel extends Level implements WorldGenLevel {
if (Shapes.joinIsNotEmpty(voxelshape, voxelshape1, BooleanOp.NOT_SAME)) {
List<PathNavigation> list = new ObjectArrayList();
@@ -142,7 +142,7 @@ index b0c95b0af6d24b9566b82b2df54eae5108b9b48b..bd64c6d0930565785deb999f43cfaa4e
// CraftBukkit start - fix SPIGOT-6362
Mob entityinsentient;
try {
-@@ -1661,16 +1671,23 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -1663,16 +1673,23 @@ public class ServerLevel extends Level implements WorldGenLevel {
try {
this.isUpdatingNavigations = true;
@@ -169,7 +169,7 @@ index b0c95b0af6d24b9566b82b2df54eae5108b9b48b..bd64c6d0930565785deb999f43cfaa4e
}
} // Paper
-@@ -2468,10 +2485,12 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -2470,10 +2487,12 @@ public class ServerLevel extends Level implements WorldGenLevel {
public void onTickingStart(Entity entity) {
ServerLevel.this.entityTickList.add(entity);
@@ -226,7 +226,7 @@ index af53372391d05dd6aa3757556418e8723b8b6d80..3f672d7c2377fca16a6d8d31cf7aaae4
+ // Paper end
}
diff --git a/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java b/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java
-index 8ad1c6f8147cfbd4677252a0d76f147786babe59..af37b1fcf8459af41482713a9e977599ae6da556 100644
+index f635b610e68d129aa0ae60c54b83da6943946436..1f0eddb0f3ded42bf312f8933def2f5c9a964651 100644
--- a/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java
+++ b/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java
@@ -71,6 +71,65 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
@@ -295,7 +295,7 @@ index 8ad1c6f8147cfbd4677252a0d76f147786babe59..af37b1fcf8459af41482713a9e977599
void removeSectionIfEmpty(long sectionPos, EntitySection<T> section) {
if (section.isEmpty()) {
this.sectionStorage.remove(sectionPos);
-@@ -456,11 +515,25 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
+@@ -468,11 +527,25 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
@Override
public void onMove() {
BlockPos blockposition = this.entity.blockPosition();
@@ -323,7 +323,7 @@ index 8ad1c6f8147cfbd4677252a0d76f147786babe59..af37b1fcf8459af41482713a9e977599
if (!this.currentSection.remove(this.entity)) {
PersistentEntitySectionManager.LOGGER.warn("Entity {} wasn't found in section {} (moving to {})", new Object[]{this.entity, SectionPos.of(this.currentSectionKey), i});
-@@ -472,6 +545,11 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
+@@ -484,6 +557,11 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
entitysection.add(this.entity);
this.currentSection = entitysection;
this.currentSectionKey = i;
diff --git a/patches/server/0759-Remove-streams-for-villager-AI.patch b/patches/server/0760-Remove-streams-for-villager-AI.patch
index 3af840ec77..3af840ec77 100644
--- a/patches/server/0759-Remove-streams-for-villager-AI.patch
+++ b/patches/server/0760-Remove-streams-for-villager-AI.patch
diff --git a/patches/server/0760-Rewrite-dataconverter-system.patch b/patches/server/0761-Rewrite-dataconverter-system.patch
index e892c4fc27..e892c4fc27 100644
--- a/patches/server/0760-Rewrite-dataconverter-system.patch
+++ b/patches/server/0761-Rewrite-dataconverter-system.patch
diff --git a/patches/server/0761-Use-Velocity-compression-and-cipher-natives.patch b/patches/server/0762-Use-Velocity-compression-and-cipher-natives.patch
index ed1f57fae4..ed1f57fae4 100644
--- a/patches/server/0761-Use-Velocity-compression-and-cipher-natives.patch
+++ b/patches/server/0762-Use-Velocity-compression-and-cipher-natives.patch
diff --git a/patches/server/0762-Reduce-worldgen-thread-worker-count-for-low-core-cou.patch b/patches/server/0763-Reduce-worldgen-thread-worker-count-for-low-core-cou.patch
index c8dd06ca73..c8dd06ca73 100644
--- a/patches/server/0762-Reduce-worldgen-thread-worker-count-for-low-core-cou.patch
+++ b/patches/server/0763-Reduce-worldgen-thread-worker-count-for-low-core-cou.patch
diff --git a/patches/server/0763-Do-not-process-entity-loads-in-CraftChunk-getEntitie.patch b/patches/server/0764-Do-not-process-entity-loads-in-CraftChunk-getEntitie.patch
index d601eb8884..d601eb8884 100644
--- a/patches/server/0763-Do-not-process-entity-loads-in-CraftChunk-getEntitie.patch
+++ b/patches/server/0764-Do-not-process-entity-loads-in-CraftChunk-getEntitie.patch
diff --git a/patches/server/0764-Async-catch-modifications-to-critical-entity-state.patch b/patches/server/0765-Async-catch-modifications-to-critical-entity-state.patch
index 3b0091079e..3e8995df49 100644
--- a/patches/server/0764-Async-catch-modifications-to-critical-entity-state.patch
+++ b/patches/server/0765-Async-catch-modifications-to-critical-entity-state.patch
@@ -8,7 +8,7 @@ Now in 1.17, this state is _even more_ critical than it was before,
so these must exist to catch stupid plugins.
diff --git a/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java b/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java
-index af37b1fcf8459af41482713a9e977599ae6da556..30c4974b4019d67cffabd3e686c782659def3ba6 100644
+index 1f0eddb0f3ded42bf312f8933def2f5c9a964651..2d3aacdae95963385ea228e73a2073a6fd96e640 100644
--- a/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java
+++ b/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java
@@ -138,6 +138,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
@@ -24,10 +24,10 @@ index af37b1fcf8459af41482713a9e977599ae6da556..30c4974b4019d67cffabd3e686c78265
private boolean addEntity(T entity, boolean existing) {
+ org.spigotmc.AsyncCatcher.catchOp("Entity add"); // Paper
- if (!this.addEntityUuid(entity)) {
- return false;
- } else {
-@@ -210,19 +212,23 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
+ // Paper start - chunk system hooks
+ if (existing) {
+ // I don't want to know why this is a generic type.
+@@ -222,19 +224,23 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
}
void startTicking(T entity) {
@@ -51,7 +51,7 @@ index af37b1fcf8459af41482713a9e977599ae6da556..30c4974b4019d67cffabd3e686c78265
this.callbacks.onTrackingEnd(entity);
this.visibleEntityStorage.remove(entity);
}
-@@ -236,6 +242,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
+@@ -248,6 +254,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
}
public void updateChunkStatus(ChunkPos chunkPos, Visibility trackingStatus) {
@@ -59,7 +59,7 @@ index af37b1fcf8459af41482713a9e977599ae6da556..30c4974b4019d67cffabd3e686c78265
long i = chunkPos.toLong();
if (trackingStatus == Visibility.HIDDEN) {
-@@ -280,6 +287,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
+@@ -292,6 +299,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
}
public void ensureChunkQueuedForLoad(long chunkPos) {
@@ -67,7 +67,7 @@ index af37b1fcf8459af41482713a9e977599ae6da556..30c4974b4019d67cffabd3e686c78265
PersistentEntitySectionManager.ChunkLoadStatus persistententitysectionmanager_b = (PersistentEntitySectionManager.ChunkLoadStatus) this.chunkLoadStatuses.get(chunkPos);
if (persistententitysectionmanager_b == PersistentEntitySectionManager.ChunkLoadStatus.FRESH) {
-@@ -324,6 +332,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
+@@ -336,6 +344,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
}
private void requestChunkLoad(long chunkPos) {
@@ -75,7 +75,7 @@ index af37b1fcf8459af41482713a9e977599ae6da556..30c4974b4019d67cffabd3e686c78265
this.chunkLoadStatuses.put(chunkPos, PersistentEntitySectionManager.ChunkLoadStatus.PENDING);
ChunkPos chunkcoordintpair = new ChunkPos(chunkPos);
CompletableFuture completablefuture = this.permanentStorage.loadEntities(chunkcoordintpair);
-@@ -337,6 +346,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
+@@ -349,6 +358,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
}
private boolean processChunkUnload(long chunkPos) {
@@ -83,7 +83,7 @@ index af37b1fcf8459af41482713a9e977599ae6da556..30c4974b4019d67cffabd3e686c78265
boolean flag = this.storeChunkSections(chunkPos, (entityaccess) -> {
entityaccess.getPassengersAndSelf().forEach(this::unloadEntity);
}, true); // CraftBukkit - add boolean for event call
-@@ -361,6 +371,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
+@@ -373,6 +383,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
}
private void processPendingLoads() {
@@ -91,7 +91,7 @@ index af37b1fcf8459af41482713a9e977599ae6da556..30c4974b4019d67cffabd3e686c78265
ChunkEntities<T> chunkentities; // CraftBukkit - decompile error
while ((chunkentities = (ChunkEntities) this.loadingInbox.poll()) != null) {
-@@ -377,6 +388,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
+@@ -389,6 +400,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
}
public void tick() {
@@ -99,7 +99,7 @@ index af37b1fcf8459af41482713a9e977599ae6da556..30c4974b4019d67cffabd3e686c78265
this.processPendingLoads();
this.processUnloads();
}
-@@ -397,6 +409,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
+@@ -409,6 +421,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
}
public void autoSave() {
@@ -107,7 +107,7 @@ index af37b1fcf8459af41482713a9e977599ae6da556..30c4974b4019d67cffabd3e686c78265
this.getAllChunksToSave().forEach((java.util.function.LongConsumer) (i) -> { // CraftBukkit - decompile error
boolean flag = this.chunkVisibility.get(i) == Visibility.HIDDEN;
-@@ -411,6 +424,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
+@@ -423,6 +436,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
}
public void saveAll() {
@@ -115,7 +115,7 @@ index af37b1fcf8459af41482713a9e977599ae6da556..30c4974b4019d67cffabd3e686c78265
LongSet longset = this.getAllChunksToSave();
while (!longset.isEmpty()) {
-@@ -518,6 +532,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
+@@ -530,6 +544,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
long i = SectionPos.asLong(blockposition); final long newSectionPos = i; // Paper - diff on change, new position section
if (i != this.currentSectionKey) {
@@ -123,7 +123,7 @@ index af37b1fcf8459af41482713a9e977599ae6da556..30c4974b4019d67cffabd3e686c78265
PersistentEntitySectionManager.this.entitySliceManager.moveEntity((Entity)this.entity); // Paper
Visibility visibility = this.currentSection.getStatus(); final Visibility oldVisibility = visibility; // Paper - diff on change - this should be OLD section visibility
// Paper start
-@@ -592,6 +607,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
+@@ -604,6 +619,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
@Override
public void onRemove(Entity.RemovalReason reason) {
diff --git a/patches/server/0765-Fix-Bukkit-NamespacedKey-shenanigans.patch b/patches/server/0766-Fix-Bukkit-NamespacedKey-shenanigans.patch
index fabf5a82e9..fabf5a82e9 100644
--- a/patches/server/0765-Fix-Bukkit-NamespacedKey-shenanigans.patch
+++ b/patches/server/0766-Fix-Bukkit-NamespacedKey-shenanigans.patch
diff --git a/patches/server/0766-Fix-merchant-inventory-not-closing-on-entity-removal.patch b/patches/server/0767-Fix-merchant-inventory-not-closing-on-entity-removal.patch
index 2ebc3b0fb5..85602ad6d7 100644
--- a/patches/server/0766-Fix-merchant-inventory-not-closing-on-entity-removal.patch
+++ b/patches/server/0767-Fix-merchant-inventory-not-closing-on-entity-removal.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Fix merchant inventory not closing on entity removal
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index bd64c6d0930565785deb999f43cfaa4eaea53195..502a11fbef542891358589f00cf4a267dca9bc9a 100644
+index a7a403d34551453a1e0502fe1f7bc139f645d917..3bb6dbdd05ed981f70556c8f905d1eeeeade30b8 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
-@@ -2576,6 +2576,11 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -2578,6 +2578,11 @@ public class ServerLevel extends Level implements WorldGenLevel {
// Spigot end
// Spigot Start
if (entity.getBukkitEntity() instanceof org.bukkit.inventory.InventoryHolder && (!(entity instanceof ServerPlayer) || entity.getRemovalReason() != Entity.RemovalReason.KILLED)) { // SPIGOT-6876: closeInventory clears death message
diff --git a/patches/server/0767-Check-requirement-before-suggesting-root-nodes.patch b/patches/server/0768-Check-requirement-before-suggesting-root-nodes.patch
index d824c5f2af..d824c5f2af 100644
--- a/patches/server/0767-Check-requirement-before-suggesting-root-nodes.patch
+++ b/patches/server/0768-Check-requirement-before-suggesting-root-nodes.patch
diff --git a/patches/server/0768-Don-t-respond-to-ServerboundCommandSuggestionPacket-.patch b/patches/server/0769-Don-t-respond-to-ServerboundCommandSuggestionPacket-.patch
index 0f32675f8e..0f32675f8e 100644
--- a/patches/server/0768-Don-t-respond-to-ServerboundCommandSuggestionPacket-.patch
+++ b/patches/server/0769-Don-t-respond-to-ServerboundCommandSuggestionPacket-.patch
diff --git a/patches/server/0769-Fix-setPatternColor-on-tropical-fish-bucket-meta.patch b/patches/server/0770-Fix-setPatternColor-on-tropical-fish-bucket-meta.patch
index 81bcca30af..81bcca30af 100644
--- a/patches/server/0769-Fix-setPatternColor-on-tropical-fish-bucket-meta.patch
+++ b/patches/server/0770-Fix-setPatternColor-on-tropical-fish-bucket-meta.patch
diff --git a/patches/server/0770-Ensure-valid-vehicle-status.patch b/patches/server/0771-Ensure-valid-vehicle-status.patch
index 2d1f854e7d..2d1f854e7d 100644
--- a/patches/server/0770-Ensure-valid-vehicle-status.patch
+++ b/patches/server/0771-Ensure-valid-vehicle-status.patch
diff --git a/patches/server/0771-Prevent-softlocked-end-exit-portal-generation.patch b/patches/server/0772-Prevent-softlocked-end-exit-portal-generation.patch
index 2286afa5f2..2286afa5f2 100644
--- a/patches/server/0771-Prevent-softlocked-end-exit-portal-generation.patch
+++ b/patches/server/0772-Prevent-softlocked-end-exit-portal-generation.patch
diff --git a/patches/server/0772-Fix-CocaoDecorator-causing-a-crash-when-trying-to-ge.patch b/patches/server/0773-Fix-CocaoDecorator-causing-a-crash-when-trying-to-ge.patch
index b415f668ab..b415f668ab 100644
--- a/patches/server/0772-Fix-CocaoDecorator-causing-a-crash-when-trying-to-ge.patch
+++ b/patches/server/0773-Fix-CocaoDecorator-causing-a-crash-when-trying-to-ge.patch
diff --git a/patches/server/0773-Don-t-log-debug-logging-being-disabled.patch b/patches/server/0774-Don-t-log-debug-logging-being-disabled.patch
index 83460a961a..83460a961a 100644
--- a/patches/server/0773-Don-t-log-debug-logging-being-disabled.patch
+++ b/patches/server/0774-Don-t-log-debug-logging-being-disabled.patch
diff --git a/patches/server/0775-Do-not-overload-I-O-threads-with-chunk-data-while-fl.patch b/patches/server/0775-Do-not-overload-I-O-threads-with-chunk-data-while-fl.patch
deleted file mode 100644
index c0add08508..0000000000
--- a/patches/server/0775-Do-not-overload-I-O-threads-with-chunk-data-while-fl.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Spottedleaf <[email protected]>
-Date: Sat, 16 Oct 2021 01:36:00 -0700
-Subject: [PATCH] Do not overload I/O threads with chunk data while flush
- saving
-
-If the chunk count is high, then the memory used by the
-chunks adds up and could cause problems. By flushing
-every so many chunks, the server will not become
-stressed for memory. It will also not increase the total
-time to save, as flush saving performs a full flush at
-the end anyways.
-
-diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
-index 236ba4c1950a3cced590f520b5349eede75fd59b..adce96d372e0f9b6c3813b2153a5dcbb32a4e75c 100644
---- a/src/main/java/net/minecraft/server/level/ChunkMap.java
-+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
-@@ -946,6 +946,16 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
- // Paper end
-
- protected void saveAllChunks(boolean flush) {
-+ // Paper start - do not overload I/O threads with too much work when saving
-+ int[] saved = new int[1];
-+ int maxAsyncSaves = 50;
-+ Runnable onChunkSave = () -> {
-+ if (++saved[0] >= maxAsyncSaves) {
-+ saved[0] = 0;
-+ com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.flush();
-+ }
-+ };
-+ // Paper end - do not overload I/O threads with too much work when saving
- if (flush) {
- List<ChunkHolder> list = (List) this.updatingChunks.getVisibleValuesCopy().stream().filter(ChunkHolder::wasAccessibleSinceLastSave).peek(ChunkHolder::refreshAccessibility).collect(Collectors.toList()); // Paper
- MutableBoolean mutableboolean = new MutableBoolean();
-@@ -968,6 +978,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
- }).filter((ichunkaccess) -> {
- return ichunkaccess instanceof ImposterProtoChunk || ichunkaccess instanceof LevelChunk;
- }).filter(this::save).forEach((ichunkaccess) -> {
-+ onChunkSave.run(); // Paper - do not overload I/O threads with too much work when saving
- mutableboolean.setTrue();
- });
- } while (mutableboolean.isTrue());
diff --git a/patches/server/0774-fix-various-menus-with-empty-level-accesses.patch b/patches/server/0775-fix-various-menus-with-empty-level-accesses.patch
index 3bda24b9c6..3bda24b9c6 100644
--- a/patches/server/0774-fix-various-menus-with-empty-level-accesses.patch
+++ b/patches/server/0775-fix-various-menus-with-empty-level-accesses.patch
diff --git a/patches/server/0781-Add-config-option-for-logging-player-ip-addresses.patch b/patches/server/0781-Add-config-option-for-logging-player-ip-addresses.patch
index f72d88e116..4e93cf35ca 100644
--- a/patches/server/0781-Add-config-option-for-logging-player-ip-addresses.patch
+++ b/patches/server/0781-Add-config-option-for-logging-player-ip-addresses.patch
@@ -65,10 +65,10 @@ index 77cb18da4f89bb89aea7d1ef5ebe3dd7acfe000d..acd581d14e0ef1fe5a6545ee67be00de
@Nullable
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
-index 03c413dfd16f415377749baa4fdd41949c6a12b9..d3c6c1b9ac00df265507db61301cae397214dca7 100644
+index 5ee0c3bb27ffbadc1e088983e643eed974753b65..fc14fc8017d89c27b0aeb10a5f38dafde5c15f53 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
-@@ -241,7 +241,7 @@ public abstract class PlayerList {
+@@ -243,7 +243,7 @@ public abstract class PlayerList {
final String s1;
if (connection.getRemoteAddress() != null) {
diff --git a/patches/server/0797-Add-player-health-update-API.patch b/patches/server/0797-Add-player-health-update-API.patch
index da94ae0e7a..96480e59ca 100644
--- a/patches/server/0797-Add-player-health-update-API.patch
+++ b/patches/server/0797-Add-player-health-update-API.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Add player health update API
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
-index 55f4a09bc27c30936e29fa2a2fe2ef0a67b8876d..67833efdd2c4babe20a01691a44ec6f153656729 100644
+index 5cdb599c6e460672ed0fe15d5c2a9d60ad22c2e3..8882651847fc9a8d2e4222f10eb389b553da48ca 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
-@@ -2152,9 +2152,11 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
+@@ -2142,9 +2142,11 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
this.getHandle().maxHealthCache = getMaxHealth();
}
@@ -22,7 +22,7 @@ index 55f4a09bc27c30936e29fa2a2fe2ef0a67b8876d..67833efdd2c4babe20a01691a44ec6f1
if (this.getHandle().queueHealthUpdatePacket) {
this.getHandle().queuedHealthUpdatePacket = packet;
} else {
-@@ -2162,7 +2164,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
+@@ -2152,7 +2154,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
}
// Paper end
}
diff --git a/patches/server/0800-Highly-optimise-single-and-multi-AABB-VoxelShapes-an.patch b/patches/server/0800-Highly-optimise-single-and-multi-AABB-VoxelShapes-an.patch
index 74fdb0cea4..ded6d6290a 100644
--- a/patches/server/0800-Highly-optimise-single-and-multi-AABB-VoxelShapes-an.patch
+++ b/patches/server/0800-Highly-optimise-single-and-multi-AABB-VoxelShapes-an.patch
@@ -1202,10 +1202,10 @@ index 97de35c614e1e9b0e825f9914173a3e1e0e53221..b35b36527294dd697d146d2ad817d791
}
}
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
-index fa7885b5ecde24e0d6bd3e8aa49668859ce275ed..0c8e0ce1e02c5865bef855ca8f68c6dfb06eca82 100644
+index fc14fc8017d89c27b0aeb10a5f38dafde5c15f53..70d648bc5e795355d28579cc2fda43c3c9eb255d 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
-@@ -946,7 +946,7 @@ public abstract class PlayerList {
+@@ -943,7 +943,7 @@ public abstract class PlayerList {
// CraftBukkit end
worldserver1.getChunkSource().addRegionTicket(net.minecraft.server.level.TicketType.POST_TELEPORT, new net.minecraft.world.level.ChunkPos(location.getBlockX() >> 4, location.getBlockZ() >> 4), 1, entityplayer.getId()); // Paper
diff --git a/patches/server/0802-Actually-unload-POI-data.patch b/patches/server/0802-Actually-unload-POI-data.patch
index 0d8ec84d4e..009a863557 100644
--- a/patches/server/0802-Actually-unload-POI-data.patch
+++ b/patches/server/0802-Actually-unload-POI-data.patch
@@ -9,19 +9,31 @@ sometimes it is.
This patch also prevents the saving/unloading of POI data when
world saving is disabled.
+diff --git a/src/main/java/net/minecraft/server/ChunkSystem.java b/src/main/java/net/minecraft/server/ChunkSystem.java
+index 2a099fe0d514f181bf2b452d5333bc29b0d29e43..81ea64443a843736f9ada97900d173c302e39ba0 100644
+--- a/src/main/java/net/minecraft/server/ChunkSystem.java
++++ b/src/main/java/net/minecraft/server/ChunkSystem.java
+@@ -270,6 +270,7 @@ public final class ChunkSystem {
+ for (int index = 0, len = chunkMap.regionManagers.size(); index < len; ++index) {
+ chunkMap.regionManagers.get(index).addChunk(holder.pos.x, holder.pos.z);
+ }
++ chunkMap.getPoiManager().dequeueUnload(holder.pos.longKey); // Paper - unload POI data
+ }
+
+ public static void onChunkHolderDelete(final ServerLevel level, final ChunkHolder holder) {
+@@ -277,6 +278,7 @@ public final class ChunkSystem {
+ for (int index = 0, len = chunkMap.regionManagers.size(); index < len; ++index) {
+ chunkMap.regionManagers.get(index).removeChunk(holder.pos.x, holder.pos.z);
+ }
++ chunkMap.getPoiManager().queueUnload(holder.pos.longKey, MinecraftServer.currentTickLong + 1); // Paper - unload POI data
+ }
+
+ public static void onChunkBorder(LevelChunk chunk, ChunkHolder holder) {
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
-index dc8d915956c04b3e9b596e3cb62f1a0498ef1787..39915f1c71fae142725ae2977a4eb0c483b4967a 100644
+index fe10c770b511fa8a38ece2bf9679492a85b28eff..a5e74d30045a171f5ed66a115fbd429e9ab412af 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
-@@ -866,6 +866,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
- }
- // Paper end
- }
-+ this.getPoiManager().dequeueUnload(holder.pos.longKey); // Paper - unload POI data
-
- this.updatingChunks.queueUpdate(pos, holder); // Paper - Don't copy
- this.modified = true;
-@@ -1017,7 +1018,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -1016,7 +1016,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
private void processUnloads(BooleanSupplier shouldKeepTicking) {
LongIterator longiterator = this.toDrop.iterator();
@@ -30,23 +42,7 @@ index dc8d915956c04b3e9b596e3cb62f1a0498ef1787..39915f1c71fae142725ae2977a4eb0c4
long j = longiterator.nextLong();
ChunkHolder playerchunk = this.updatingChunks.queueRemove(j); // Paper - Don't copy
-@@ -1065,6 +1066,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
- this.regionManagers.get(index).removeChunk(holder.pos.x, holder.pos.z);
- }
- // Paper end
-+ this.getPoiManager().queueUnload(holder.pos.longKey, MinecraftServer.currentTickLong + 1); // Paper - unload POI data
- if (ichunkaccess instanceof LevelChunk) {
- ((LevelChunk) ichunkaccess).setLoaded(false);
- }
-@@ -1094,6 +1096,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
- for (int index = 0, len = this.regionManagers.size(); index < len; ++index) {
- this.regionManagers.get(index).removeChunk(holder.pos.x, holder.pos.z);
- }
-+ this.getPoiManager().queueUnload(holder.pos.longKey, MinecraftServer.currentTickLong + 1); // Paper - unload POI data
- } // Paper end
- } finally { this.unloadingPlayerChunk = unloadingBefore; } // Paper - do not allow ticket level changes while unloading chunks
-
-@@ -1169,6 +1172,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -1164,6 +1164,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
}
this.poiManager.loadInData(pos, chunkHolder.poiData);
chunkHolder.tasks.forEach(Runnable::run);
diff --git a/patches/server/0806-Only-write-chunk-data-to-disk-if-it-serializes-witho.patch b/patches/server/0806-Only-write-chunk-data-to-disk-if-it-serializes-witho.patch
index 8596aa0004..fca5a00257 100644
--- a/patches/server/0806-Only-write-chunk-data-to-disk-if-it-serializes-witho.patch
+++ b/patches/server/0806-Only-write-chunk-data-to-disk-if-it-serializes-witho.patch
@@ -47,7 +47,7 @@ index 8ff8855c5267379b3a5f5d8baa4a275ffee2c4bf..fc3442b4c7e1f22080fe6bf36d4fade1
ByteBuffer bytebuffer = ByteBuffer.wrap(this.buf, 0, this.count);
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
-index 6986a170f37f70e8eb89d79d5d2615a06a5e0f0c..c31b9a6b1d4548d507ecb60d42ca9f96f49f6c4b 100644
+index f38ec8914e1953091ab65aa3aaefc886d3eede8a..c2356ed1a00fd8087cca285be5e7f6a5442e73fb 100644
--- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
@@ -298,10 +298,17 @@ public class RegionFileStorage implements AutoCloseable {
@@ -79,9 +79,9 @@ index 6986a170f37f70e8eb89d79d5d2615a06a5e0f0c..c31b9a6b1d4548d507ecb60d42ca9f96
- }
+ // Paper - move into try block to only write if successfully serialized
}
-
- // Paper start
-@@ -359,4 +363,13 @@ public class RegionFileStorage implements AutoCloseable {
+ // Paper start
+ return;
+@@ -358,4 +362,13 @@ public class RegionFileStorage implements AutoCloseable {
}
}
diff --git a/patches/server/0821-Validate-usernames.patch b/patches/server/0821-Validate-usernames.patch
index 8422e53312..c032b67744 100644
--- a/patches/server/0821-Validate-usernames.patch
+++ b/patches/server/0821-Validate-usernames.patch
@@ -56,10 +56,10 @@ index acd581d14e0ef1fe5a6545ee67be00deff589879..553eb8e437b07376dbfc54b0018bcc3f
GameProfile gameprofile = this.server.getSingleplayerProfile();
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
-index 0c8e0ce1e02c5865bef855ca8f68c6dfb06eca82..04d2f469dc045152c4fad0427d4d16d80d508f3f 100644
+index 70d648bc5e795355d28579cc2fda43c3c9eb255d..67f90c75aa4858bf1575bf7b0a62b8113de7c2ea 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
-@@ -717,7 +717,7 @@ public abstract class PlayerList {
+@@ -714,7 +714,7 @@ public abstract class PlayerList {
for (int i = 0; i < this.players.size(); ++i) {
entityplayer = (ServerPlayer) this.players.get(i);
diff --git a/patches/server/0824-Expose-vanilla-BiomeProvider-from-WorldInfo.patch b/patches/server/0824-Expose-vanilla-BiomeProvider-from-WorldInfo.patch
index c07b3000af..7a4e27a8cd 100644
--- a/patches/server/0824-Expose-vanilla-BiomeProvider-from-WorldInfo.patch
+++ b/patches/server/0824-Expose-vanilla-BiomeProvider-from-WorldInfo.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] Expose vanilla BiomeProvider from WorldInfo
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
-index 68c0bb1d493b3de3c3e80018a1655ec968b0316a..a4433426efd0823cd8145a50b38127f63e90adc9 100644
+index 857af8ed37c10723d6cd81d7f3c2ba6169021050..28e2f22cc2e5b6dd47705cdd5095ff2394979c8f 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -562,7 +562,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -18,7 +18,7 @@ index 68c0bb1d493b3de3c3e80018a1655ec968b0316a..a4433426efd0823cd8145a50b38127f6
biomeProvider = gen.getDefaultBiomeProvider(worldInfo);
}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-index fe0b8b623b8853aaa4fd0a105f502cfebb763dfb..3fe38a9a6f4c25b91a25bc2320a7d7fcbe446d9d 100644
+index 96ad0b334b2985c295be4f20df06e6eb73fbb22f..2b57b60a3ecb5ac170f2d70532dc8439c5a3459f 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -1212,7 +1212,7 @@ public final class CraftServer implements Server {
@@ -31,10 +31,10 @@ index fe0b8b623b8853aaa4fd0a105f502cfebb763dfb..3fe38a9a6f4c25b91a25bc2320a7d7fc
biomeProvider = generator.getDefaultBiomeProvider(worldInfo);
}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-index beee040abf846492cefabe985c5286b00fc6bc63..f68a1d5adac4d88c462371c484464bbea22d3147 100644
+index 5138182d8004aec69848d10b8cc63453c1e8808f..7916426a9d7953c2cc15a319adea8d982b63b773 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-@@ -201,6 +201,30 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+@@ -200,6 +200,30 @@ public class CraftWorld extends CraftRegionAccessor implements World {
public int getPlayerCount() {
return world.players().size();
}
diff --git a/patches/server/0835-Freeze-Tick-Lock-API.patch b/patches/server/0835-Freeze-Tick-Lock-API.patch
index a3dcc6117b..bb6de3cbf8 100644
--- a/patches/server/0835-Freeze-Tick-Lock-API.patch
+++ b/patches/server/0835-Freeze-Tick-Lock-API.patch
@@ -59,10 +59,10 @@ index 8dc54061802f0253193bda79bded1d5265591519..44c0f77bdeeb9061b1dfcd904ed2c639
if (this.isInPowderSnow && this.canFreeze()) {
this.setTicksFrozen(Math.min(this.getTicksRequiredToFreeze(), i + 1));
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
-index e12dcc33e859950efec36b91ad9a43e435545d5b..2a6c67634c31c332102d24bef293da1bacd0c000 100644
+index df3c8e5342f9284970371d81f84c5ccabaaa00c2..0bae967bb9830784d98c2a1cccca512660c6324a 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
-@@ -673,6 +673,17 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
+@@ -642,6 +642,17 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
return this.getHandle().isFullyFrozen();
}
diff --git a/patches/server/0841-Implement-regenerateChunk.patch b/patches/server/0841-Implement-regenerateChunk.patch
index 3f73a6ed62..ba57a50388 100644
--- a/patches/server/0841-Implement-regenerateChunk.patch
+++ b/patches/server/0841-Implement-regenerateChunk.patch
@@ -6,7 +6,7 @@ Subject: [PATCH] Implement regenerateChunk
Co-authored-by: Jason Penilla <[email protected]>
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-index f68a1d5adac4d88c462371c484464bbea22d3147..1bbc73dcdf890a9383795ffeb0d368293f7146a5 100644
+index 7916426a9d7953c2cc15a319adea8d982b63b773..73e7181655b78f5bff90d07edfe6c5408cc08235 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -139,6 +139,7 @@ import org.bukkit.util.Vector;
@@ -17,7 +17,7 @@ index f68a1d5adac4d88c462371c484464bbea22d3147..1bbc73dcdf890a9383795ffeb0d36829
private final ServerLevel world;
private WorldBorder worldBorder;
-@@ -431,27 +432,62 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+@@ -419,27 +420,62 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@Override
public boolean regenerateChunk(int x, int z) {
org.spigotmc.AsyncCatcher.catchOp("chunk regenerate"); // Spigot
diff --git a/patches/server/0854-Replace-player-chunk-loader-system.patch b/patches/server/0854-Replace-player-chunk-loader-system.patch
index cb165d3086..c06805bfb0 100644
--- a/patches/server/0854-Replace-player-chunk-loader-system.patch
+++ b/patches/server/0854-Replace-player-chunk-loader-system.patch
@@ -1272,10 +1272,10 @@ index 66afd752fd7d327e141d49b477f07e1ff3645d02..2a26d03fba2f3b37f176be9e47954ef9
// Paper end
diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java
-index 1eb71004a19866590a3d27fa6e72842934989177..7034af8ad42940c5af6b9032b9873ce36c55a2a7 100644
+index b575d73ae0ff2e4f09a6a1f6fb061ca3da2cedf1..6939ef9b1fe782980e77c351d8a385a573d6a8e6 100644
--- a/src/main/java/net/minecraft/server/MCUtil.java
+++ b/src/main/java/net/minecraft/server/MCUtil.java
-@@ -647,7 +647,8 @@ public final class MCUtil {
+@@ -636,7 +636,8 @@ public final class MCUtil {
});
worldData.addProperty("name", world.getWorld().getName());
@@ -1284,9 +1284,9 @@ index 1eb71004a19866590a3d27fa6e72842934989177..7034af8ad42940c5af6b9032b9873ce3
+ worldData.addProperty("tick-view-distance", world.getChunkSource().chunkMap.playerChunkManager.getTargetTickViewDistance()); // Paper - replace chunk loader system
worldData.addProperty("keep-spawn-loaded", world.keepSpawnInMemory);
worldData.addProperty("keep-spawn-loaded-range", world.paperConfig().spawn.keepSpawnLoadedRange * 16);
- worldData.addProperty("visible-chunk-count", visibleChunks.size());
+ worldData.addProperty("visible-chunk-count", allChunks.size());
diff --git a/src/main/java/net/minecraft/server/level/ChunkHolder.java b/src/main/java/net/minecraft/server/level/ChunkHolder.java
-index 5482be03a667939ff009b6810d5cc90c8601e983..11cd31691307749e925930c4b6e10e3f3b4fad25 100644
+index 73712d6b9c828427d4c066c6d8672534575f3793..a041161dee9a857d43c83fb677dba7e90a6a5d24 100644
--- a/src/main/java/net/minecraft/server/level/ChunkHolder.java
+++ b/src/main/java/net/minecraft/server/level/ChunkHolder.java
@@ -76,6 +76,17 @@ public class ChunkHolder {
@@ -1305,9 +1305,9 @@ index 5482be03a667939ff009b6810d5cc90c8601e983..11cd31691307749e925930c4b6e10e3f
+ }
+ // Paper end - no-tick view distance
- // Paper start - optimise anyPlayerCloseEnoughForSpawning
- // cached here to avoid a map lookup
-@@ -268,7 +279,7 @@ public class ChunkHolder {
+ // Paper start
+ public void onChunkAdd() {
+@@ -273,7 +284,7 @@ public class ChunkHolder {
public void blockChanged(BlockPos pos) {
if (!pos.isInsideBuildHeightAndWorldBoundsHorizontal(levelHeightAccessor)) return; // Paper - SPIGOT-6086 for all invalid locations; avoid acquiring locks
@@ -1316,7 +1316,7 @@ index 5482be03a667939ff009b6810d5cc90c8601e983..11cd31691307749e925930c4b6e10e3f
if (chunk != null) {
int i = this.levelHeightAccessor.getSectionIndex(pos.getY());
-@@ -284,14 +295,15 @@ public class ChunkHolder {
+@@ -289,14 +300,15 @@ public class ChunkHolder {
}
public void sectionLightChanged(LightLayer lightType, int y) {
@@ -1336,7 +1336,7 @@ index 5482be03a667939ff009b6810d5cc90c8601e983..11cd31691307749e925930c4b6e10e3f
if (chunk != null) {
int j = this.lightEngine.getMinLightSection();
-@@ -394,9 +406,28 @@ public class ChunkHolder {
+@@ -399,9 +411,28 @@ public class ChunkHolder {
}
public void broadcast(Packet<?> packet, boolean onlyOnWatchDistanceEdge) {
@@ -1369,7 +1369,7 @@ index 5482be03a667939ff009b6810d5cc90c8601e983..11cd31691307749e925930c4b6e10e3f
public CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> getOrScheduleFuture(ChunkStatus targetStatus, ChunkMap chunkStorage) {
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
-index 39915f1c71fae142725ae2977a4eb0c483b4967a..77c89376495d90d0e7cbf6cd02c9a1c8d9a4340b 100644
+index a5e74d30045a171f5ed66a115fbd429e9ab412af..47657f20652a80f50a2e46207c9c05d1a12111b4 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -218,6 +218,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
@@ -1422,7 +1422,7 @@ index 39915f1c71fae142725ae2977a4eb0c483b4967a..77c89376495d90d0e7cbf6cd02c9a1c8
}
// Paper end
// Paper start
-@@ -1449,11 +1453,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -1447,11 +1451,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
completablefuture1.thenAcceptAsync((either) -> {
either.ifLeft((chunk) -> {
this.tickingGenerated.getAndIncrement();
@@ -1435,12 +1435,12 @@ index 39915f1c71fae142725ae2977a4eb0c483b4967a..77c89376495d90d0e7cbf6cd02c9a1c8
});
}, (runnable) -> {
this.mainThreadMailbox.tell(ChunkTaskPriorityQueueSorter.message(holder, runnable));
-@@ -1622,33 +1622,24 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -1620,33 +1620,24 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
int k = this.viewDistance;
this.viewDistance = j;
- this.distanceManager.updatePlayerTickets(this.viewDistance + 1);
-- Iterator objectiterator = this.updatingChunks.getVisibleValuesCopy().iterator(); // Paper
+- Iterator objectiterator = net.minecraft.server.ChunkSystem.getUpdatingChunkHolders(this.level).iterator(); // Paper
-
- while (objectiterator.hasNext()) {
- ChunkHolder playerchunk = (ChunkHolder) objectiterator.next();
@@ -1478,16 +1478,16 @@ index 39915f1c71fae142725ae2977a4eb0c483b4967a..77c89376495d90d0e7cbf6cd02c9a1c8
if (chunk != null) {
this.playerLoadedChunk(player, packet, chunk);
-@@ -1679,7 +1670,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -1677,7 +1668,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
void dumpChunks(Writer writer) throws IOException {
CsvOutput csvwriter = CsvOutput.builder().addColumn("x").addColumn("z").addColumn("level").addColumn("in_memory").addColumn("status").addColumn("full_status").addColumn("accessible_ready").addColumn("ticking_ready").addColumn("entity_ticking_ready").addColumn("ticket").addColumn("spawning").addColumn("block_entity_count").addColumn("ticking_ticket").addColumn("ticking_level").addColumn("block_ticks").addColumn("fluid_ticks").build(writer);
- TickingTracker tickingtracker = this.distanceManager.tickingTracker();
+ // Paper - replace loader system
- ObjectBidirectionalIterator objectbidirectionaliterator = this.updatingChunks.getVisibleMap().clone().long2ObjectEntrySet().fastIterator(); // Paper
+ Iterator<ChunkHolder> objectbidirectionaliterator = net.minecraft.server.ChunkSystem.getVisibleChunkHolders(this.level).iterator(); // Paper
while (objectbidirectionaliterator.hasNext()) {
-@@ -1695,7 +1686,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -1693,7 +1684,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
// CraftBukkit - decompile error
csvwriter.writeRow(chunkcoordintpair.x, chunkcoordintpair.z, playerchunk.getTicketLevel(), optional.isPresent(), optional.map(ChunkAccess::getStatus).orElse(null), optional1.map(LevelChunk::getFullStatus).orElse(null), ChunkMap.printFuture(playerchunk.getFullChunkFuture()), ChunkMap.printFuture(playerchunk.getTickingChunkFuture()), ChunkMap.printFuture(playerchunk.getEntityTickingChunkFuture()), this.distanceManager.getTicketDebugString(i), this.anyPlayerCloseEnoughForSpawning(chunkcoordintpair), optional1.map((chunk) -> {
return chunk.getBlockEntities().size();
@@ -1496,7 +1496,7 @@ index 39915f1c71fae142725ae2977a4eb0c483b4967a..77c89376495d90d0e7cbf6cd02c9a1c8
return chunk.getBlockTicks().count();
}).orElse(0), optional1.map((chunk) -> {
return chunk.getFluidTicks().count();
-@@ -1929,15 +1920,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -1927,15 +1918,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
this.removePlayerFromDistanceMaps(player); // Paper - distance maps
}
@@ -1513,7 +1513,7 @@ index 39915f1c71fae142725ae2977a4eb0c483b4967a..77c89376495d90d0e7cbf6cd02c9a1c8
}
-@@ -1945,7 +1928,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -1943,7 +1926,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
SectionPos sectionposition = SectionPos.of((EntityAccess) player);
player.setLastSectionPos(sectionposition);
@@ -1522,7 +1522,7 @@ index 39915f1c71fae142725ae2977a4eb0c483b4967a..77c89376495d90d0e7cbf6cd02c9a1c8
return sectionposition;
}
-@@ -1990,65 +1973,40 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -1988,65 +1971,40 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
int k1;
int l1;
@@ -1610,7 +1610,7 @@ index 39915f1c71fae142725ae2977a4eb0c483b4967a..77c89376495d90d0e7cbf6cd02c9a1c8
}
public void addEntity(Entity entity) {
-@@ -2417,7 +2375,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -2415,7 +2373,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
double vec3d_dx = player.getX() - this.entity.getX();
double vec3d_dz = player.getZ() - this.entity.getZ();
// Paper end - remove allocation of Vec3D here
@@ -1797,10 +1797,10 @@ index f581a9f79b2357118d912a15344ff94df3b0c50e..d1b5c25b7455174e908cd6ed66789fa7
+ */ // Paper - replace old loader system
}
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
-index 96a232f22b1c270b91635ce9c7c6cacc63b026cc..59acbf6249f8f5285504c0ddea448a3433d1d68d 100644
+index 3b549ac6d07484a09dc6521cb4f3ab3b3cc979e9..ea1b8f4fd49678f39b1036ae6be880bacc6997f8 100644
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
-@@ -844,17 +844,10 @@ public class ServerChunkCache extends ChunkSource {
+@@ -665,17 +665,10 @@ public class ServerChunkCache extends ChunkSource {
// Paper end
public boolean isPositionTicking(long pos) {
@@ -1822,7 +1822,7 @@ index 96a232f22b1c270b91635ce9c7c6cacc63b026cc..59acbf6249f8f5285504c0ddea448a34
}
public void save(boolean flush) {
-@@ -911,6 +904,7 @@ public class ServerChunkCache extends ChunkSource {
+@@ -732,6 +725,7 @@ public class ServerChunkCache extends ChunkSource {
this.level.getProfiler().popPush("chunks");
if (tickChunks) {
this.level.timings.chunks.startTiming(); // Paper - timings
@@ -1830,7 +1830,7 @@ index 96a232f22b1c270b91635ce9c7c6cacc63b026cc..59acbf6249f8f5285504c0ddea448a34
this.tickChunks();
this.level.timings.chunks.stopTiming(); // Paper - timings
}
-@@ -1024,13 +1018,13 @@ public class ServerChunkCache extends ChunkSource {
+@@ -845,13 +839,13 @@ public class ServerChunkCache extends ChunkSource {
// Paper end - optimise chunk tick iteration
ChunkPos chunkcoordintpair = chunk1.getPos();
@@ -1846,7 +1846,7 @@ index 96a232f22b1c270b91635ce9c7c6cacc63b026cc..59acbf6249f8f5285504c0ddea448a34
this.level.tickChunk(chunk1, k);
if ((chunksTicked++ & 1) == 0) net.minecraft.server.MinecraftServer.getServer().executeMidTickTasks(); // Paper
}
-@@ -1259,6 +1253,7 @@ public class ServerChunkCache extends ChunkSource {
+@@ -1080,6 +1074,7 @@ public class ServerChunkCache extends ChunkSource {
public boolean pollTask() {
try {
boolean execChunkTask = com.destroystokyo.paper.io.chunk.ChunkTaskManager.pollChunkWaitQueue() || ServerChunkCache.this.level.asyncChunkTaskManager.pollNextChunkTask(); // Paper
@@ -1855,10 +1855,10 @@ index 96a232f22b1c270b91635ce9c7c6cacc63b026cc..59acbf6249f8f5285504c0ddea448a34
return true;
} else {
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index 502a11fbef542891358589f00cf4a267dca9bc9a..9dc4a1d9082a0cb3ab6848698c3fc41a5f57e380 100644
+index 3bb6dbdd05ed981f70556c8f905d1eeeeade30b8..e71ae32d9827d8a6fb8543abdba7627897ac9f2e 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
-@@ -680,7 +680,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -682,7 +682,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
gameprofilerfiller.push("checkDespawn");
entity.checkDespawn();
gameprofilerfiller.pop();
@@ -1867,7 +1867,7 @@ index 502a11fbef542891358589f00cf4a267dca9bc9a..9dc4a1d9082a0cb3ab6848698c3fc41a
Entity entity1 = entity.getVehicle();
if (entity1 != null) {
-@@ -713,7 +713,10 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -715,7 +715,10 @@ public class ServerLevel extends Level implements WorldGenLevel {
@Override
public boolean shouldTickBlocksAt(long chunkPos) {
@@ -1879,7 +1879,7 @@ index 502a11fbef542891358589f00cf4a267dca9bc9a..9dc4a1d9082a0cb3ab6848698c3fc41a
}
protected void tickTime() {
-@@ -2457,7 +2460,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -2459,7 +2462,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
private boolean isPositionTickingWithEntitiesLoaded(long chunkPos) {
// Paper start - optimize is ticking ready type functions
ChunkHolder chunkHolder = this.chunkSource.chunkMap.getVisibleChunkIfPresent(chunkPos);
@@ -1900,10 +1900,10 @@ index b35b36527294dd697d146d2ad817d7911145ae8c..18c3d4aecf498f78040c27336d2ea56f
+ public final int getViewDistance() { throw new UnsupportedOperationException("Use PlayerChunkLoader"); } // Paper - placeholder
}
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
-index 04d2f469dc045152c4fad0427d4d16d80d508f3f..525b385cfd216f8ff2de02439c5cd0f8d77c5d42 100644
+index 67f90c75aa4858bf1575bf7b0a62b8113de7c2ea..b588e14b2826bda5b03b4fc497efcb96b566541a 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
-@@ -274,7 +274,7 @@ public abstract class PlayerList {
+@@ -276,7 +276,7 @@ public abstract class PlayerList {
boolean flag1 = gamerules.getBoolean(GameRules.RULE_REDUCEDDEBUGINFO);
// Spigot - view distance
@@ -1912,7 +1912,7 @@ index 04d2f469dc045152c4fad0427d4d16d80d508f3f..525b385cfd216f8ff2de02439c5cd0f8
player.getBukkitEntity().sendSupportedChannels(); // CraftBukkit
playerconnection.send(new ClientboundCustomPayloadPacket(ClientboundCustomPayloadPacket.BRAND, (new FriendlyByteBuf(Unpooled.buffer())).writeUtf(this.getServer().getServerModName())));
playerconnection.send(new ClientboundChangeDifficultyPacket(worlddata.getDifficulty(), worlddata.isDifficultyLocked()));
-@@ -952,8 +952,8 @@ public abstract class PlayerList {
+@@ -949,8 +949,8 @@ public abstract class PlayerList {
// CraftBukkit start
LevelData worlddata = worldserver1.getLevelData();
entityplayer1.connection.send(new ClientboundRespawnPacket(worldserver1.dimensionTypeId(), worldserver1.dimension(), BiomeManager.obfuscateSeed(worldserver1.getSeed()), entityplayer1.gameMode.getGameModeForPlayer(), entityplayer1.gameMode.getPreviousGameModeForPlayer(), worldserver1.isDebug(), worldserver1.isFlat(), flag, entityplayer1.getLastDeathLocation()));
@@ -1923,7 +1923,7 @@ index 04d2f469dc045152c4fad0427d4d16d80d508f3f..525b385cfd216f8ff2de02439c5cd0f8
entityplayer1.spawnIn(worldserver1);
entityplayer1.unsetRemoved();
entityplayer1.connection.teleport(new Location(worldserver1.getWorld(), entityplayer1.getX(), entityplayer1.getY(), entityplayer1.getZ(), entityplayer1.getYRot(), entityplayer1.getXRot()));
-@@ -1522,7 +1522,7 @@ public abstract class PlayerList {
+@@ -1519,7 +1519,7 @@ public abstract class PlayerList {
public void setViewDistance(int viewDistance) {
this.viewDistance = viewDistance;
@@ -1932,7 +1932,7 @@ index 04d2f469dc045152c4fad0427d4d16d80d508f3f..525b385cfd216f8ff2de02439c5cd0f8
Iterator iterator = this.server.getAllLevels().iterator();
while (iterator.hasNext()) {
-@@ -1537,7 +1537,7 @@ public abstract class PlayerList {
+@@ -1534,7 +1534,7 @@ public abstract class PlayerList {
public void setSimulationDistance(int simulationDistance) {
this.simulationDistance = simulationDistance;
@@ -2079,10 +2079,10 @@ index d870cefbe5b7485f423817f4f639e3e2a304640c..2292cb0e0c1a3e0ed34b941f028136bf
@Nullable
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-index 1bbc73dcdf890a9383795ffeb0d368293f7146a5..c4f7aa9ffb72d2bc555ace64bb8cedc5c2545d8b 100644
+index 73e7181655b78f5bff90d07edfe6c5408cc08235..1e179d8ff339c6647fed1a3d2a1c010737d37dc6 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-@@ -2281,43 +2281,56 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+@@ -2234,43 +2234,56 @@ public class CraftWorld extends CraftRegionAccessor implements World {
// Spigot start
@Override
public int getViewDistance() {
@@ -2148,7 +2148,7 @@ index 1bbc73dcdf890a9383795ffeb0d368293f7146a5..c4f7aa9ffb72d2bc555ace64bb8cedc5
// Paper end - view distance api
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
-index dc5ef870e23ba9497fcb9c2961334d928213f4c2..77339926519057b1c878761780ff2d6621f5ccb7 100644
+index 86d9250ce0a49635362a2710bf3c064936d1c77f..16fa7bdb8cc4bcad01ed33455cf1e51b69e2f720 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -541,45 +541,80 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
diff --git a/patches/server/0856-Force-close-world-loading-screen.patch b/patches/server/0856-Force-close-world-loading-screen.patch
index e55a25678b..1f75753d30 100644
--- a/patches/server/0856-Force-close-world-loading-screen.patch
+++ b/patches/server/0856-Force-close-world-loading-screen.patch
@@ -10,10 +10,10 @@ so we do not need that. The client only needs the chunk it is currently in to
be loaded to close the loading screen, so we just send an empty one.
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
-index 525b385cfd216f8ff2de02439c5cd0f8d77c5d42..26345ddd671175b9dfd457750ae0da7042ec649f 100644
+index b588e14b2826bda5b03b4fc497efcb96b566541a..5a5ea1f9d6e978916d32b170ecf7f848d2524303 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
-@@ -432,6 +432,16 @@ public abstract class PlayerList {
+@@ -429,6 +429,16 @@ public abstract class PlayerList {
// Paper start - move vehicle into method so it can be called above - short circuit around that code
onPlayerJoinFinish(player, worldserver1, s1);
diff --git a/patches/server/0857-Fix-falling-block-spawn-methods.patch b/patches/server/0857-Fix-falling-block-spawn-methods.patch
index 3c1270d7c9..f72c2de50f 100644
--- a/patches/server/0857-Fix-falling-block-spawn-methods.patch
+++ b/patches/server/0857-Fix-falling-block-spawn-methods.patch
@@ -21,10 +21,10 @@ index d1fca0e3227b5f37c11367548be362f5a49b6a71..5628940cd3c3566c5db2beda506d4f20
if (Snowball.class.isAssignableFrom(clazz)) {
entity = new net.minecraft.world.entity.projectile.Snowball(world, x, y, z);
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-index c4f7aa9ffb72d2bc555ace64bb8cedc5c2545d8b..3aa4363793ea0b2de4224010b51e9798bc77ec2c 100644
+index 1e179d8ff339c6647fed1a3d2a1c010737d37dc6..ea26283265902cf05151283c4abc7db9e30f2559 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-@@ -1417,7 +1417,12 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+@@ -1405,7 +1405,12 @@ public class CraftWorld extends CraftRegionAccessor implements World {
Validate.notNull(material, "Material cannot be null");
Validate.isTrue(material.isBlock(), "Material must be a block");
@@ -38,7 +38,7 @@ index c4f7aa9ffb72d2bc555ace64bb8cedc5c2545d8b..3aa4363793ea0b2de4224010b51e9798
return (FallingBlock) entity.getBukkitEntity();
}
-@@ -1426,7 +1431,12 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+@@ -1414,7 +1419,12 @@ public class CraftWorld extends CraftRegionAccessor implements World {
Validate.notNull(location, "Location cannot be null");
Validate.notNull(data, "BlockData cannot be null");
diff --git a/patches/server/0860-Fix-save-problems-on-shutdown.patch b/patches/server/0860-Fix-save-problems-on-shutdown.patch
index 4ae525c1f1..b07c4721de 100644
--- a/patches/server/0860-Fix-save-problems-on-shutdown.patch
+++ b/patches/server/0860-Fix-save-problems-on-shutdown.patch
@@ -55,10 +55,10 @@ index df08b7afcf19ce694a87c25e8589c0c72521c5db..4d920031300a9801debc2eb39a4d3cb9
if (isOversleep) return canOversleep();// Paper - because of our changes, this logic is broken
return this.forceTicks || this.runningTask() || Util.getMillis() < (this.mayHaveDelayedTasks ? this.delayedTasksMaxNextTickTime : this.nextTickTime);
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index 9dc4a1d9082a0cb3ab6848698c3fc41a5f57e380..95c2f8d70eff220dd53a6779e105a9bb67e47b6a 100644
+index e71ae32d9827d8a6fb8543abdba7627897ac9f2e..eceaa1f2ede1c068f9090d13bf9d3b3afaa08cc3 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
-@@ -1282,7 +1282,13 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -1284,7 +1284,13 @@ public class ServerLevel extends Level implements WorldGenLevel {
}
}
diff --git a/patches/server/0880-Use-username-instead-of-display-name-in-PlayerList-g.patch b/patches/server/0880-Use-username-instead-of-display-name-in-PlayerList-g.patch
index 0c9a4f6f91..2accf61444 100644
--- a/patches/server/0880-Use-username-instead-of-display-name-in-PlayerList-g.patch
+++ b/patches/server/0880-Use-username-instead-of-display-name-in-PlayerList-g.patch
@@ -6,10 +6,10 @@ Subject: [PATCH] Use username instead of display name in
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
-index 26345ddd671175b9dfd457750ae0da7042ec649f..e1b6017953edffcea0be81b70cf7b22ce8c0570d 100644
+index 5a5ea1f9d6e978916d32b170ecf7f848d2524303..5999d85e38951503fc83b40cfe39671921ae5088 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
-@@ -1486,7 +1486,7 @@ public abstract class PlayerList {
+@@ -1483,7 +1483,7 @@ public abstract class PlayerList {
// CraftBukkit start
public ServerStatsCounter getPlayerStats(ServerPlayer entityhuman) {
ServerStatsCounter serverstatisticmanager = entityhuman.getStats();
diff --git a/patches/server/0882-Pass-ServerLevel-for-gamerule-callbacks.patch b/patches/server/0882-Pass-ServerLevel-for-gamerule-callbacks.patch
index 649425acbe..cb27fe4e42 100644
--- a/patches/server/0882-Pass-ServerLevel-for-gamerule-callbacks.patch
+++ b/patches/server/0882-Pass-ServerLevel-for-gamerule-callbacks.patch
@@ -158,10 +158,10 @@ index 3c93bfeb94168f832904a8462ae23b06e81e080d..468c635d31cfa8051666bbefce8df4b4
this.onChanged(server);
}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-index 3aa4363793ea0b2de4224010b51e9798bc77ec2c..a5d8dfc77475845be7c6d37eed04fb19eeef1c0c 100644
+index ea26283265902cf05151283c4abc7db9e30f2559..d5f2a83296ae25e41629f3ab114c067dda1c7f33 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-@@ -1921,7 +1921,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+@@ -1909,7 +1909,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
// Paper end
GameRules.Value<?> handle = this.getHandle().getGameRules().getRule(CraftWorld.getGameRulesNMS().get(rule));
handle.deserialize(event.getValue()); // Paper
@@ -170,7 +170,7 @@ index 3aa4363793ea0b2de4224010b51e9798bc77ec2c..a5d8dfc77475845be7c6d37eed04fb19
return true;
}
-@@ -1961,7 +1961,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+@@ -1949,7 +1949,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
// Paper end
GameRules.Value<?> handle = this.getHandle().getGameRules().getRule(CraftWorld.getGameRulesNMS().get(rule.getName()));
handle.deserialize(event.getValue()); // Paper
diff --git a/patches/server/0892-Don-t-tick-markers.patch b/patches/server/0892-Don-t-tick-markers.patch
index eaf0d00d81..d21ff9fe5a 100644
--- a/patches/server/0892-Don-t-tick-markers.patch
+++ b/patches/server/0892-Don-t-tick-markers.patch
@@ -22,10 +22,10 @@ index 68f99e93ed3e843b4001a7a27620f88a48b85e67..0dc96c39151ec4dbeec3947cb17606f5
}
});
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index 95c2f8d70eff220dd53a6779e105a9bb67e47b6a..43df2ed0f464a0e7be188b7efea723215dbaf527 100644
+index eceaa1f2ede1c068f9090d13bf9d3b3afaa08cc3..e5a64e70020487b15825a865623afa45b0ae59d4 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
-@@ -2493,6 +2493,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -2495,6 +2495,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
}
public void onTickingStart(Entity entity) {
diff --git a/patches/server/0901-Add-Alternate-Current-redstone-implementation.patch b/patches/server/0901-Add-Alternate-Current-redstone-implementation.patch
index e155fcdd0a..f0b286c6c2 100644
--- a/patches/server/0901-Add-Alternate-Current-redstone-implementation.patch
+++ b/patches/server/0901-Add-Alternate-Current-redstone-implementation.patch
@@ -2008,7 +2008,7 @@ index 0000000000000000000000000000000000000000..33cd90c30c22200a4e1ae64f40a0bf78
+ }
+}
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index 43df2ed0f464a0e7be188b7efea723215dbaf527..43aa4eee00502d1f05acc5f7e4e92db98063accd 100644
+index e5a64e70020487b15825a865623afa45b0ae59d4..684063b8433f78ef0adf0de1057ea24720b32181 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -219,6 +219,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
@@ -2019,7 +2019,7 @@ index 43df2ed0f464a0e7be188b7efea723215dbaf527..43aa4eee00502d1f05acc5f7e4e92db9
public static Throwable getAddToWorldStackTrace(Entity entity) {
return new Throwable(entity + " Added to world at " + new java.util.Date());
}
-@@ -2482,6 +2483,13 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -2484,6 +2485,13 @@ public class ServerLevel extends Level implements WorldGenLevel {
return this.entityManager.canPositionTick(pos.toLong()); // Paper
}
diff --git a/patches/server/0909-Prevent-empty-items-from-being-added-to-world.patch b/patches/server/0909-Prevent-empty-items-from-being-added-to-world.patch
index 286893bc24..2e13972f86 100644
--- a/patches/server/0909-Prevent-empty-items-from-being-added-to-world.patch
+++ b/patches/server/0909-Prevent-empty-items-from-being-added-to-world.patch
@@ -7,10 +7,10 @@ The previous solution caused a bunch of bandaid fixes inorder to resolve edge ca
Just simply prevent them from being added to the world instead.
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index 43aa4eee00502d1f05acc5f7e4e92db98063accd..3d986805c89d22330d6ad1e09760940b2f399214 100644
+index 684063b8433f78ef0adf0de1057ea24720b32181..96bb0e56f12437037b598cd7baabf369e5994517 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
-@@ -1437,6 +1437,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
+@@ -1439,6 +1439,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
// WorldServer.LOGGER.warn("Tried to add entity {} but it was marked as removed already", EntityTypes.getKey(entity.getType())); // CraftBukkit
return false;
} else {
diff --git a/patches/server/0919-More-Teleport-API.patch b/patches/server/0919-More-Teleport-API.patch
index 735a1effb8..e133efa140 100644
--- a/patches/server/0919-More-Teleport-API.patch
+++ b/patches/server/0919-More-Teleport-API.patch
@@ -29,10 +29,10 @@ index 13c253b1d7f6d4713135baba2bc2ad9cd84224f8..0e365529695321ab2b164c75d4c67bdd
d0 = to.getX();
d1 = to.getY();
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
-index 2a6c67634c31c332102d24bef293da1bacd0c000..b80cc0938b2b3928f4450f1314a9fbd7ea9c116b 100644
+index 0bae967bb9830784d98c2a1cccca512660c6324a..cc7b76a66d87ffa30c4bf6e3c1123df86d73b571 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
-@@ -571,15 +571,33 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
+@@ -540,15 +540,33 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
@Override
public boolean teleport(Location location, TeleportCause cause) {
@@ -69,10 +69,10 @@ index 2a6c67634c31c332102d24bef293da1bacd0c000..b80cc0938b2b3928f4450f1314a9fbd7
// Let the server handle cross world teleports
if (location.getWorld() != null && !location.getWorld().equals(this.getWorld())) {
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
-index 77339926519057b1c878761780ff2d6621f5ccb7..6f0ffd1895a9c392b643f3595e709ec3706c39b4 100644
+index 16fa7bdb8cc4bcad01ed33455cf1e51b69e2f720..a8e63a417ab4971ce35569dbb0b792635e8366ae 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
-@@ -1135,7 +1135,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
+@@ -1135,13 +1135,92 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
@Override
public void setRotation(float yaw, float pitch) {
@@ -88,9 +88,6 @@ index 77339926519057b1c878761780ff2d6621f5ccb7..6f0ffd1895a9c392b643f3595e709ec3
+ // Paper end
}
- // Paper start - Chunk priority
-@@ -1150,8 +1158,79 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
-
@Override
public boolean teleport(Location location, PlayerTeleportEvent.TeleportCause cause) {
+ // Paper start - Teleport API
@@ -169,7 +166,7 @@ index 77339926519057b1c878761780ff2d6621f5ccb7..6f0ffd1895a9c392b643f3595e709ec3
location.checkFinite();
ServerPlayer entity = this.getHandle();
-@@ -1164,7 +1243,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
+@@ -1154,7 +1233,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
return false;
}
@@ -178,7 +175,7 @@ index 77339926519057b1c878761780ff2d6621f5ccb7..6f0ffd1895a9c392b643f3595e709ec3
return false;
}
-@@ -1182,7 +1261,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
+@@ -1172,7 +1251,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
}
// If this player is riding another entity, we must dismount before teleporting.
@@ -187,7 +184,7 @@ index 77339926519057b1c878761780ff2d6621f5ccb7..6f0ffd1895a9c392b643f3595e709ec3
// SPIGOT-5509: Wakeup, similar to riding
if (this.isSleeping()) {
-@@ -1204,7 +1283,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
+@@ -1194,7 +1273,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
// Check if the fromWorld and toWorld are the same.
if (fromWorld == toWorld) {
diff --git a/patches/server/0923-Warn-on-plugins-accessing-faraway-chunks.patch b/patches/server/0923-Warn-on-plugins-accessing-faraway-chunks.patch
index 069ec6a90b..6b7a35a426 100644
--- a/patches/server/0923-Warn-on-plugins-accessing-faraway-chunks.patch
+++ b/patches/server/0923-Warn-on-plugins-accessing-faraway-chunks.patch
@@ -18,10 +18,10 @@ index 9467ccaa1d73e1913495a46919aee530e749977d..5a2a1d394852d39ea576624586f7fa73
private static boolean isOutsideSpawnableHeight(int y) {
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-index a5d8dfc77475845be7c6d37eed04fb19eeef1c0c..f0b14914438840bd819fa7da8b76f4fcc13704d0 100644
+index d5f2a83296ae25e41629f3ab114c067dda1c7f33..4c5145ed32a22080a88d25e2dbb7cfde2f6bbc4f 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
-@@ -314,9 +314,24 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+@@ -313,9 +313,24 @@ public class CraftWorld extends CraftRegionAccessor implements World {
public boolean setSpawnLocation(int x, int y, int z) {
return this.setSpawnLocation(x, y, z, 0.0F);
}
@@ -46,7 +46,7 @@ index a5d8dfc77475845be7c6d37eed04fb19eeef1c0c..f0b14914438840bd819fa7da8b76f4fc
// Paper start - add ticket to hold chunk for a little while longer if plugin accesses it
net.minecraft.world.level.chunk.LevelChunk chunk = world.getChunkSource().getChunkAtIfLoadedImmediately(x, z);
if (chunk == null) {
-@@ -432,6 +447,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+@@ -420,6 +435,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@Override
public boolean regenerateChunk(int x, int z) {
org.spigotmc.AsyncCatcher.catchOp("chunk regenerate"); // Spigot
@@ -54,7 +54,7 @@ index a5d8dfc77475845be7c6d37eed04fb19eeef1c0c..f0b14914438840bd819fa7da8b76f4fc
// Paper start - implement regenerateChunk method
final ServerLevel serverLevel = this.world;
final net.minecraft.server.level.ServerChunkCache serverChunkCache = serverLevel.getChunkSource();
-@@ -525,6 +541,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+@@ -513,6 +529,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@Override
public boolean loadChunk(int x, int z, boolean generate) {
org.spigotmc.AsyncCatcher.catchOp("chunk load"); // Spigot
@@ -62,7 +62,7 @@ index a5d8dfc77475845be7c6d37eed04fb19eeef1c0c..f0b14914438840bd819fa7da8b76f4fc
// Paper start - Optimize this method
ChunkPos chunkPos = new ChunkPos(x, z);
ChunkAccess immediate = world.getChunkSource().getChunkAtIfLoadedImmediately(x, z); // Paper
-@@ -589,6 +606,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+@@ -577,6 +594,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@Override
public boolean addPluginChunkTicket(int x, int z, Plugin plugin) {
@@ -70,7 +70,7 @@ index a5d8dfc77475845be7c6d37eed04fb19eeef1c0c..f0b14914438840bd819fa7da8b76f4fc
Preconditions.checkArgument(plugin != null, "null plugin");
Preconditions.checkArgument(plugin.isEnabled(), "plugin is not enabled");
-@@ -670,6 +688,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+@@ -658,6 +676,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@Override
public void setChunkForceLoaded(int x, int z, boolean forced) {
@@ -78,7 +78,7 @@ index a5d8dfc77475845be7c6d37eed04fb19eeef1c0c..f0b14914438840bd819fa7da8b76f4fc
this.getHandle().setChunkForced(x, z, forced);
}
-@@ -981,6 +1000,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+@@ -969,6 +988,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@Override
public int getHighestBlockYAt(int x, int z, org.bukkit.HeightMap heightMap) {
@@ -86,9 +86,9 @@ index a5d8dfc77475845be7c6d37eed04fb19eeef1c0c..f0b14914438840bd819fa7da8b76f4fc
// Transient load for this tick
return this.world.getChunk(x >> 4, z >> 4).getHeight(CraftHeightMap.toNMS(heightMap), x, z);
}
-@@ -2238,6 +2258,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+@@ -2330,6 +2350,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
+ // Spigot end
// Paper start
- @Override
public java.util.concurrent.CompletableFuture<Chunk> getChunkAtAsync(int x, int z, boolean gen, boolean urgent) {
+ warnUnsafeChunk("getting a faraway chunk async", x, z); // Paper
if (Bukkit.isPrimaryThread()) {
diff --git a/patches/server/0936-Workaround-for-client-lag-spikes-MC-162253.patch b/patches/server/0936-Workaround-for-client-lag-spikes-MC-162253.patch
index 4e963d9792..7da4def3c8 100644
--- a/patches/server/0936-Workaround-for-client-lag-spikes-MC-162253.patch
+++ b/patches/server/0936-Workaround-for-client-lag-spikes-MC-162253.patch
@@ -16,10 +16,10 @@ Co-authored-by: =?UTF-8?q?Dani=C3=ABl=20Goossens?= <[email protected]>
Co-authored-by: Nassim Jahnke <[email protected]>
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
-index 77c89376495d90d0e7cbf6cd02c9a1c8d9a4340b..649355158ed435e242a48f4aaa4578bcc2a808dd 100644
+index 47657f20652a80f50a2e46207c9c05d1a12111b4..c2c01988bf3b6fbb0a7a4716373c2ff0cffce27d 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
-@@ -2171,6 +2171,46 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -2169,6 +2169,46 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
}
@@ -66,7 +66,7 @@ index 77c89376495d90d0e7cbf6cd02c9a1c8d9a4340b..649355158ed435e242a48f4aaa4578bc
// Paper start - Anti-Xray - Bypass
private void playerLoadedChunk(ServerPlayer player, MutableObject<java.util.Map<Object, ClientboundLevelChunkWithLightPacket>> cachedDataPackets, LevelChunk chunk) {
if (cachedDataPackets.getValue() == null) {
-@@ -2179,6 +2219,45 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
+@@ -2177,6 +2217,45 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
Boolean shouldModify = chunk.getLevel().chunkPacketBlockController.shouldModify(player, chunk);
player.trackChunk(chunk.getPos(), (Packet) cachedDataPackets.getValue().computeIfAbsent(shouldModify, (s) -> {